Добрый день!
В процессе изучения учебника Столярова «Азы программирования» в главе 2.5.2 «Посимвольный ввод информации» возник вопрос.
В тексте книги описывается программа для перемножения двух заданных чисел. Предварительно правильность написания чисел проверяется с помощью процедуры ReadLongint
program MultReadLongint;
procedure ReadLongint(var ok: boolean; var EndResult: longint);
var
c: char;
posit: integer;
res: longint;
begin
res := 0;
posit := 0;
repeat
read(c);
posit := posit + 1
until (c <> ' ') and (c <> #10);
while (c <> ' ') and (c <> #10) do
begin
if (c < '0') or (c > '9') then
begin
writeln('Incorrect simbol ', c, ' on the position ', posit);
readln;
ok := false;
exit
end;
res := res * 10 + ord(c) - ord('0');
read(c);
posit := posit + 1
end;
EndResult := res;
ok := true
end;
var
a, b: longint;
ok: boolean;
begin
writeln('Enter the first number: ');
repeat
ReadLongint(ok, a);
until ok;
writeln('Enter the second number: ');
repeat
ReadLongint(ok, b);
until ok;
writeln(a, ' times ', b, ' is ', a*b)
end.
Но у такой программы есть слабое место. При вводе первого числа как ‘3 5’ программа будет считать, что последовательно введены число №1 - 3 и число №2 - 5.
Причина понятна - у автора пробел прерывает цикл, но поток ввода не очищается => число 5 уже находится в потоке ввода при новом старте процедуры для числа №2.
Собственно, один вариант решения проблемы я нашёл: переписать в процедуре ReadLongint участок с
while (c <> ' ') and (c <> #10) do
на
while c <> #10 do
Но потом я попробовал решить проблему еще одним способом - в первоначальный вариант программы добавить в конце процедуры ReadLongint очистку потока ввода c помощью readln. т.е. с
end;
EndResult := res;
ok := true
end;
поменять на
end;
readln;
EndResult := res;
ok := true
end;
Но результат получился не таким, как я ожидал. Все работает корректно если первое число равно, к примеру, ’3 ’. Если же число равно просто ‘3’, то после выполнения readln сработает классическим для себя образом - переведет строку и будет ждать ввода Enter.
Почему же тогда в месте, где его изначально использовал автор,
if (c < '0') or (c > '9') then
begin
writeln('Incorrect simbol ', c, ' on the position ', posit);
readln;
ok := false;
exit
end;
readln работает всегда безошибочно не переводя строку?