PascalABCNet, при перезапуске кода функция вызывается два раза
Вчера сделал калькулятор, нажал на кнопку проверить здоровье кода и увидел, что у меня было 64% из-за устаревших конструкций. Я почитай официальную документацию, переписал код. Теперь здоровье кода показывало 134%, но при вводе знака, после перезапуска программы, функция с проверкой на правильно введённый знак перезапускается два раза, а после можно снова пользоваться программой. Вот вывод:
Введите знак(/,*,+,-): *
Введите первое число: 1
Введите второе число: 2
Ответ: 2
Введите знак(/,*,+,-): Вы используете несуществующий символ для вычисления!
Введите знак(/,*,+,-): Вы используете несуществующий символ для вычисления!
Введите знак(/,*,+,-):
Обновленный код:
{program calculator;}
label restart;
begin
var rest: integer;
restart: rest := 0;
while rest <> 1 do
begin
var sign := ReadChar('Введите знак(/,*,+,-):');
if (sign <> '-') and (sign <> '+') and (sign <> '/') and (sign <> '*') then begin
writeln('Вы используете несуществующий символ для вычисления!');
goto restart;
end;
var a := ReadInteger('Введите первое число: ');
var b := ReadInteger('Введите второе число: ');
if sign = '+' then begin
writeln('Ответ: ', a + b);
end;
if sign = '-' then begin
writeln('Ответ: ', a - b);
end;
if sign = '/' then begin
if b <> 0 then begin
writeln('Ответ: ', a / b);
end
else
writeln('Нельзя делить на 0!');
goto restart;
end;
if sign = '*' then begin
writeln('Ответ: ', a * b);
end;
end;
end.
Ответы (1 шт):
Дело в том, что функция ReadChar() принимает на вход все символы, введенные пользователем, включая Enter, который состоит из двух символов CrLf (Carriage return + Line feed) — это комбинация двух символов: возврата каретки и перевода строки. Они используются в системах Windows и DOS. Символ возврата каретки возвращает курсор в начало строки, а символ перевода строки переносит курсор на новую строку.
Если вы немного измените строку вывода сообщения о недопустимом символе:
writeln('Вы используете несуществующий символ для вычисления с кодом ['+ord(sign) + ']!');
то сможете это проверить.
Как с этим бороться?
После ряда экспериментов с ReadChar(), ReadLn(), ReadlnChar() сложилось впечатление, что PascalABC не приспособлен для ввода данных в цикле (или у меня такая реализация IDE), поскольку буфер ввода с клавиатуры не очищается перед следующим вводом и туда проскакивают как минимум CrLf.
Возможно, существуют функции / процедуры, которые очищают буфер ввода с клавиатуры перед следующим вводом, но я таких не нашел.
Сделал более-менее стабильно (у меня) работающий вариант:
{program calculator;}
var
signs: set of char := ['+', '-', '*', '/']; // задаем множество допустимых символов
a, b: Integer;
buf: string;
sign: char;
begin
while True do
begin
buf := '';
write('Введите знак(/,*,+,-) или # для выхода: ');
while buf = '' do Readln(buf);
sign := buf[1];
if sign = '#' then break;
if sign in signs then // проверяем, допустим ли символ - есть ли он во множестве
begin
a := ReadInteger('Введите первое число: ');
b := ReadInteger('Введите второе число: ');
case sign of // вместо нескольких if
'+': writeln('Ответ: ', a + b);
'-': writeln('Ответ: ', a - b);
'/':
begin
if b <> 0 then writeln('Ответ: ', a / b)
else writeln('Нельзя делить на 0!');
end;
'*': writeln('Ответ: ', a * b);
end;
end
else writeln('Вы используете несуществующий символ для вычисления с кодом [' + ord(sign) + ']!'); // выводим не только сообщение, но и ASCII - код недопустимого символа (для отладки, например)
end;
writeln('Калькулятор выключен');
end.
Введите знак(/,*,+,-) или # для выхода: +
Введите первое число: 1
Введите второе число: 3
Ответ: 4
Введите знак(/,*,+,-) или # для выхода: 45
Вы используете несуществующий символ для вычисления с кодом [52]!
Введите знак(/,*,+,-) или # для выхода: /
Введите первое число: 45
Введите второе число: 5
Ответ: 9
Введите знак(/,*,+,-) или # для выхода: *
Введите первое число: 25
Введите второе число: 45
Ответ: 1125
Введите знак(/,*,+,-) или # для выхода: *89
Введите первое число:
78
Введите второе число: 88
Ответ: 6864
Введите знак(/,*,+,-) или # для выхода: #
Калькулятор выключен