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

А вообще какие шаблоны, тут надо 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 лайк

Как в PascalABC.NET использовать EventHandler, а именно: события public event SpeakStarted, SpeakCompleted, SpeakProgress, BookmarkReached, VoiceChange, PhonemeReached, VisemeReached, StateChanged в unit Speech, namespace System.Speech.Synthesis?

event используется так:

type
  t1 = class
    event ev: procedure(o: object; e: System.EventArgs);
    
    procedure CallEv;
    begin
      var ev := ev;
      if ev<>nil then ev(self, new System.EventArgs);
    end;
    
  end;
  
begin
  var a := new t1;
  a.ev += (o,e)->Writeln('Ивент вызван');
  a.CallEv;
end.

EventHandler объявлен так:

type EventHandler = procedure(o: object; e: System.EventArgs);

Но, обратите внимание, это не синоним типа, а объявление нового типа делегата.
Разница в том, что typeof(EventHandler) = typeof(EventHandler), потому что это 2 обращения к одному и тому же типу.
А каждый раз как вы пишете тип procedure(o: object; e: System.EventArgs) - вы создаёте новый анонимный тип делегата.

Достаточно и правильно ли использовать ss.SpeakStarted += (o,e)->begin end, чтобы реагировать на событие в следующем примере?

uses System.Speech.Synthesis;
{$reference System.Speech.dll}
  
begin
  var ss: SpeechSynthesizer := new SpeechSynthesizer;
  ss.SpeakStarted += (o,e)->begin end;
  ss.Speak('');
end.

Как удалить ненужную переменную после её описания?

Ну, вы как бы отреагировали… И в ответ ничего не сделали. Я в своём примере сделал чтоб на консоль выводило строку в момент вызова, чтоб было визуально заметно когда ивент вызывается…

А если вы пытались сделать минимальный пример - лучше (o,e)->exit(), немного короче получается.

Что значит удалить?