Помощь новичкам

Я прочитал, но мне не удалось ответить на свой вопрос.

Прочитали или пробежались? Пример реализации Transform ведь делает то что вы спрашиваете - вызов переданной функции внутри другой подпрограммы.

Как в заголовке подпрограммы указать, что тип может быть любым? procedure Backspace(f: <T>-><T>; var a: <T>; params i: array of <T>) не работает.

Полный код (на всякий случай):

procedure Backspace(f: <T>-><T>; var a: <T>; params i: array of <T>);
begin
  var x := Console.CursorLeft;
  var y := Console.CursorTop; // сохранение положения курсора
  a := f(i); // значение функции
  var m: integer;
  if (Console.BufferHeight > Console.WindowHeight) then m := Console.LargestWindowWidth - 3 else m := Console.LargestWindowWidth; // расчёт количества символов, которое влезет в окно текущей ширины
  var l := a.ToString.Length; // длина введённых данных
  x += l;
  while (x >= m) do
  begin
    x -= m;
    y += 1; // расчёт положения курсора сразу после ввода
  end;
  Console.CursorLeft := x;
  Console.CursorTop := y; // восстановления положения курсора
end;

Ну как минимум потому что учите более базовый синтаксис перед тем как приступать чему то более сложному. Шаблоны записываются так:

procedure p1<T>(a: T);

<> стоит только после имени подпрограммы и перечисляет все имена которые считать шаблонным типом. А в описании параметров надо писать просто T.

<> в типах параметров может быть только если вы используете шаблонный класс/запись в параметрах:

type
  t1<TVal> = class
    val: TVal;
  end;
  
procedure p1<TArg>(a: t1<TArg>);

А вообще какие шаблоны, тут надо f: ()->string. Возвращать надо именно string, потому что, к примеру, при вводе числа - можно поставить пробелы слева и справа от числа при вводе. Тогда получится что ввели больше символов, чем надо чтоб представить это число после .ToString .

И аргументы f тут ни к чему, вы же пишете не инвоук для вызова между доменами.

Это всё для поддержки функций, у которых вывод осуществляется и в параметры, и в Result, например, function TryRead(var x: число): boolean.

Тогда следует считывать в строку, брать её в длину и преобразовывать строку в тип, соответствующий параетру-функции?

TryRead тут не сработает, раз число нельзя вводить напрямую. Но если нужна проверка ввода - то её надо делать ручками:

procedure Backspace(f: ()->string);
begin
  //ToDo
end;

begin
  Backspace(()->
  begin
    while true do
    begin
      Result := ReadString;
      if Result.All(ch->ch.IsDigit or char.IsWhiteSpace(ch)) then
        break;
      Writeln('Повторите ввод');
    end;
  end);
end.

Как направить в ReadLexem строку вместо ввода?

ReadLexem имеет алгоритм, оптимизированный на потоки данных (System.IO.Stream) и привязанный к потоку ввода. Можно перенаправить весь поток ввода на строку в памяти (в том числе временно).

Но это скорее костыли, потому что если вам надо вытащить слово из строки - надо использовать методы работы со строками, а не пытаться прикрутить методы работы с потоками. Тогда код будет и эффективнее, и проще:

##
var ind := 1;
var s := ReadString;
while ind<>s.Length do
  s.ReadWord(ind).Println;

Почему не работает?

uses GraphWPF;

begin
var x:=ReadInteger; или var x:=ReadReal;
end.

Как мне теперь считать значение с клавиатуры?

System.FormatException: Входная строка имела неверный формат.

Всё работает. Вводить надо в ту же строку ввода, что и в консольной программе. Если не делать ошибок при вводе, такого исключения быть не должно.

Проблема появляется, только если подключить GraphWPF. У меня всё работает только в окне IDE. Как только ввод направляется прямо из окна консольного приложения, так сразу вылетает исключение. (Кстати, исключение можно не заметить, если не вызвать запись в окно консоли, поскольку запрос на ввод числа и последующее исключение не вызывают выделения консольного окна.)

В случае с ReadString окно не реагирует на нажатия клавиш при вводе, кроме как при нажатии клавиш пропадает выделение.

Такое чувство, что ввод отрезан от окна консоли.

Графические приложения не предназначены для работы с окном консоли

1 лайк

Ясно. Тогда как считывать что-либо с клавиатуры (особенно не отдельные символы, а подлиннее, но и отдельные будут полезны)?

Без окна консоли:

Графический экран при подключение через uses будеть работать всегда, не даёт помехи для ввода с клавиатуры

Так у меня не работает ReadInteger при выполнении без связи с оболочкой (Shift+F9):

image

Программы с модулем GraphWPF не предназначены для компиляции и выполнения без связи с оболочкой, если в них используются подпрограммы ввода?

Если нет консоли, а Вы указываете консольный ввод, что по-Вашему программа должна делать?

1 лайк

Это работает только в IDE.

и иметь возможность запустить эту скомпилированную программу с подключённым модулем GraphWPF?

Никак. GraphWPF для этого не создавался

1 лайк