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

Вы можете сами определить тип со всеми проверками

type Natural = record
  i: integer := 1;
  static function operator-(a, b: Natural): Natural;
  begin
    if a.i > b.i then
      Result.i := a.i - b.i
    else
      raise new System.OverflowException();
  end;
  
  static function operator implicit(i: integer): Natural;
  begin
    if i > 0 then
      Result.i := i
    else
      raise new System.OverflowException();
  end;
  
  static function operator implicit(n: Natural): integer;
  begin
    Result := n.i;
  end;
  
  public function ToString: string; override;
  begin
    Result := i.ToString;
  end;
end;

begin
  var n1: Natural := 3;
  var n2: Natural := 4;
  writeln(n2-n1);
  writeln(n1-n2);
end.

Почему при выполнении

  var Одобрение: char;
  while true do
  begin
    Одобрение := ReadChar;
    if (Одобрение = 'Y') or (Одобрение = 'N') then break;
    Writeln('Неподходящее значение. Повторите ввод.');
  end;

если ввести неподходящее значение, то “Неподходящее значение. Повторите ввод.” выводится трижды, при этом 2 раза игнорируется Одобрение := ReadChar, хотя

  var Одобрение: char;
  while true do
  begin
    Одобрение := ReadChar;
    Одобрение := ReadChar;
    Одобрение := ReadChar;
    if (Одобрение = 'Y') or (Одобрение = 'N') then break;
    Writeln('Неподходящее значение. Повторите ввод.');
  end;

работает, как ожидалось?

Как сделать код одобрения более компактным?

ReadChar читает 1 символ. А когда вы вводите что то и нажимаете Enter - вы посылаете сам 1 символ + 2 символа переноса строки (#13#10).

Read без ln должно использоваться если вы ожидаете что в той же строке ввода, через пробел или ещё как - могут быть ещё другие данные. Во всех остальные случаях - надо использовать Readln***.


А за то что вы тут делаете - я бы руки отрывал. Надо не только нажать Y или N, так ещё и Enter! Этот алгоритм делается как то так:

  while true do
    case Console.ReadKey(true).KeyChar.ToUpper of
      'Y': break;
      'N': Halt;
    end;

А чтобы отладить программу, нужно будет постоянно заменять Console.ReadKey, ведь в противном случае программа не запустится в Pascal ABC NET? Что тогда делать?

не использовать Console.ReadKey

1 лайк

Страдать извращениями.

{$define NoConsole}

begin
  while true do
    case
    {$ifdef NoConsole} ReadlnChar
    {$else} Console.ReadKey(true).KeyChar
    {$endif NoConsole}
    .ToUpper of
      'Y': break;
      'N': Halt;
    end;
end.

Зачем второй раз идентификатор писать?

Чтоб легче было увидеть к какому $ifdef относится $endif.

Почему нажатие без Enter не работает через функцию?

function YNChoice: boolean;
begin
  {$define NoConsole}
  while true do
    case
    {$ifdef NoConsole} ReadlnChar
    {$else} Console.ReadKey(true).KeyChar
    {$endif}
    .ToUpper of
      'Y':
      begin
        Result:=True;
        {$undef NoConsole}
        exit;
      end;
      'N':
      begin
        Result:=False;
        {$undef NoConsole}
        exit;
      end;
    end;
end;
begin
  Writeln(YNChoice);
  Readln;
  Readln;
end.

Как ждать нажатия клавиши перед закрытием консольного окна после завершения программы, кроме способа с двумя Readln?

Это так не работает. Директивы компилятора выполняются ещё во время компиляции а не выполнения программы.
А {$define NoConsole} должно быть именно в начале программы. Чтоб можно было в 1 месте поставить пробел перед $, таким образом переключив всю программу в режим использования консоли.

У меня без него всё прекрасно работает. Хотя когда вы запускаете с консолью - NoConsole надо таки отрубать.

Если что, я имел в виду при выполнении программы, которая была получена после нажатия на “Имя программы.pas” правой кнопкой мыши и нажатия “Компилировать”.

В данном случае это ничего не меняет. Эффект тот же что и Shift+F9 из IDE.

На что влияет опция “RedirectConsoleIO” в файле настроек? То, что она перенаправляет ввод/вывод консоли, итак понятно, поэтому прошу подробнее.

Во входном текстовом файле нужно в каждом слове длиннее 4 букв случайно переставить со второй по предпоследнюю букву и записать в другой файл. Например:

«По результатам исследований одного английского университета, не имеет значения, в каком порядке расположены буквы в слове. Главное, чтобы первая и последняя буквы были на месте. Остальные буквы могут следовать в полном беспорядке, всё равно текст читается без проблем. Причиной этого является то, что мы не читаем каждую букву по отдельности, а всё слово целиком.» 123-123456, 123456+7890

Получив:

«По рзуьелаттам идессваолний одного агйнскилого унесвиритета, не имеет зечнания, в каком поярдке рсжопоалены буквы в слове. Гавлное, чтобы превая и плдсоеняя буквы были на месте. Отсьланые буквы могут сдовлеать в полном брсопяедке, всё равно тескт читеатся без прболем. Пчрииной этого яляевтся то, что мы не чтиаем кажудю букву по отьлондести, а всё слово циелком.» 123-123456, 12345+67890

Как и предполагалось, возможность присваивать значения срезам весьма кстати: слово[2: слово.Length-1]:=… , а вот разбивка на слова методом .ToWords удаляет всё лишнее вроде стоп-символов, усложняя довольно простую задачу.

Можно ли как-то сделать выборку без Regex, кроме посимвольного сравнения времён TP?

А это что за шифры?

.ToWords это для более общих и простых заданий. Он сам - вызывает .Split, который уже прекрасно настраивается.

1 лайк

А почему Вам Regexы не нравятся? Они позволяют узнать позицию каждого слова в отличие от ToWords

Их школьный учитель поставил такое условие, чтобы возможно позже рассмотреть вариант решения через выражения.

Сергей, то не шифры, а исправляя лишнюю разметку сделал опечатку. Суть в том, что цифры не буквы

Хз где писать такие вопросы, напишу тут. Можно ли унаследовать класс из неуправляемой библиотеки. Если да, то как ?

В неуправляемых библиотеках не бывает классов. В них бывают только подпрограммы.

Если в коде, из которого создаётся неуправляемая .dll есть классы - в готовой .dll они будут выглядеть как безымянные записи, существующие только в контексте конкретной подпрограммы.

А в коде который подключает подпрограммы из этой .dll - надо объявить использованные записи самостоятельно.

теперь для меня еще темнее стало с подключением библиотек :grinning:, возможно я не правильно все воспринимаю. Я просто хотел подключить SFML и не совсем понимаю как. Но я как понял, что надо описывать функции которые вложенные в этой dll.Если это так, то спасибо за ответ.