Как ввести число с клавиатуры в Паскале: от простого к сложному

Ввод данных с клавиатуры — одна из базовых операций в программировании, с которой сталкивается каждый начинающий разработчик. В языке Pascal эта задача решается с помощью стандартных процедур read и readln, но даже здесь есть нюансы, которые могут вызвать ошибки у новичков. Например, почему программа «зависает» при вводе букв вместо чисел? Или как правильно обработать дробные числа с плавающей точкой?

В этой статье мы разберём все актуальные способы ввода чисел в Pascal, включая обработку исключений, проверку корректности данных и работу с разными типами переменных. Вы узнаете, как избежать типичных ошибок, научитесь использовать буфер ввода и даже реализуете собственную функцию для безопасного чтения чисел. Материал будет полезен как школьникам, изучающим основы алгоритмизации, так и студентам, которые пишут лабораторные работы на Free Pascal или Turbo Pascal.

1. Базовый ввод чисел: процедуры read и readln

Самый простой способ получить число от пользователя — использовать стандартные процедуры read и readln. Они работают одинаково для целых (integer) и вещественных (real) чисел, но есть важные различия в их поведении:

  • 🔢 read(x) — считывает значение в переменную x, но не переходит на новую строку. Следующий ввод начнётся с того же места.
  • readln(x) — считывает значение и перемещает курсор на следующую строку. Рекомендуется для интерактивных программ.
  • ⚠️ readln без параметров — просто пропускает текущую строку (полезно для очистки буфера).

Пример кода для ввода целого числа:

program InputExample;

var

num: integer;

begin

writeln('Введите целое число:');

readln(num); // Ожидает ввод числа и нажатия Enter

writeln('Вы ввели:', num);

end.

Для дробных чисел используйте тип real:

var

price: real;

begin

writeln('Введите цену товара:');

readln(price);

writeln('Стоимость:', price:0:2); // Форматирование до 2 знаков после запятой

end.

⚠️ Внимание: Если пользователь введёт букву вместо числа, программа завершится с ошибкой Runtime error 106 (Invalid numeric format). Это одна из самых распространённых проблем у начинающих.
📊 Какой компилятор Pascal вы используете?
Free Pascal
Turbo Pascal
Lazarus
PascalABC.NET
Другой

2. Проблемы с буфером ввода и как их избежать

Многие новички сталкиваются с ситуацией, когда после ввода числа программа «проглатывает» следующий readln. Это происходит из-за особенностей работы буфера клавиатуры. Например:

var

age: integer;

name: string;

begin

writeln('Введите возраст:');

readln(age);

writeln('Введите имя:');

readln(name); // Эта строка может быть пропущена!

end.

Проблема возникает потому, что после нажатия Enter в буфере остаётся символ новой строки (#13#10). Чтобы её решить, используйте один из приёмов:

  • 🔄 Добавляйте лишний readln после ввода числа:
    readln(age);
    

    readln; // Очистка буфера

    writeln('Введите имя:');

    readln(name);

  • 📥 Используйте read вместо readln для чисел, если следующий ввод тоже число.
  • 🛠️ Применяйте низкоуровневые функции вроде ReadKey из модуля Crt (только для Turbo Pascal).
Способ очистки буфераПример кодаКогда использовать
Дополнительный readlnreadln(x); readln;Универсальное решение для консольных программ
Модуль Crtuses Crt;... while KeyPressed do ReadKey;Только для Turbo Pascal под DOS
Проверка на #13if Input^ = #13 then Readln;Для опытных программистов

3. Проверка корректности ввода: защита от ошибок

Один из ключевых навыков при работе с вводом данных — умение обрабатывать некорректные данные. В Pascal для этого есть несколько подходов:

Способ 1: Цикл с проверкой (для целых чисел)

var

num: integer;

inputStr: string;

code: integer;

begin

repeat

writeln('Введите число от 1 до 100:');

readln(inputStr);

val(inputStr, num, code); // Пытаемся преобразовать строку в число

if (code <> 0) or (num < 1) or (num > 100) then

writeln('Ошибка! Введите корректное число.');

until (code = 0) and (num >= 1) and (num <= 100);

end.

Здесь используется функция val, которая пытается преобразовать строку в число. Если преобразование невозможно, переменная code будет содержать ненулевое значение.

Способ 2: Обработка исключений (try..except)

Более современный подход — использование механизма исключений (работает в Free Pascal и Delphi):

var

num: integer;

begin

repeat

try

writeln('Введите число:');

readln(num);

Break; // Выходим из цикла, если ввод корректен

except

on EConvertError do

writeln('Ошибка! Введено не число.');

end;

until false;

end.

⚠️ Внимание: Механизм исключений не работает в классическом Turbo Pascal 7.0. Для старых компиляторов используйте только первый способ с val.

Использовать val для преобразования строки в число|Проверять код ошибки (code)|Ограничивать диапазон значений (например, 1..100)|Выводить понятное сообщение об ошибке-->

4. Ввод дробных чисел (real) и особенности форматирования

Работа с вещественными числами (real, double, extended) имеет свои нюансы. Главная проблема — несоответствие между тем, как пользователь вводит число (например, «3,14»), и внутренним представлением в Pascal (где разделитель — точка).

В большинстве современных компиляторов (включая Free Pascal) поддерживаются оба формата, но для надёжности лучше:

  • 📌 Явно указывать пользователю использовать точку: writeln('Введите число (разделитель — точка):');
  • 🔄 Преобразовывать запятую в точку перед обработкой (см. пример ниже).
  • 🎯 Использовать тип double вместо real для большей точности.

Пример обработки ввода с заменой запятой на точку:

var

inputStr: string;

num: real;

code: integer;

i: integer;

begin

writeln('Введите дробное число:');

readln(inputStr);

// Заменяем запятую на точку

for i:= 1 to Length(inputStr) do

if inputStr[i] =',' then

inputStr[i]:='.';

val(inputStr, num, code);

if code = 0 then

writeln('Вы ввели:', num:0:2)

else

writeln('Ошибка ввода!');

end.

Для вывода вещественных чисел используйте форматирование. Например, num:0:2 означает:

  • 0 — минимальная ширина поля (авто).
  • 2 — количество знаков после запятой.

5. Альтернативные способы ввода: файлы и аргументы командной строки

Помимо клавиатуры, числа в программу на Pascal можно передать другими способами. Это полезно для автоматизации или работы с большими объёмами данных.

Ввод из файла

Если числа хранятся в текстовом файле (например, input.txt), используйте следующий код:

var

f: text;

num: integer;

begin

Assign(f,'input.txt');

Reset(f);

while not Eof(f) do

begin

readln(f, num);

writeln('Прочитано число:', num);

end;

Close(f);

end.

Аргументы командной строки

В Free Pascal можно передавать числа как параметры при запуске программы:

program ArgsExample;

var

num: integer;

begin

if ParamCount > 0 then

begin

val(ParamStr(1), num, code);

if code = 0 then

writeln('Передано число:', num)

else

writeln('Ошибка: первый параметр не число!');

end;

end.

Чтобы передать число при запуске, используйте командную строку:

fpc ArgsExample.pas

./ArgsExample 42

⚠️ Внимание: В Turbo Pascal для работы с аргументами командной строки требуется модуль Dos, а синтаксис отличается. Используйте ParamStr(1) и ParamCount только в современных компиляторах.
Как передать несколько чисел через аргументы?

Можно передавать несколько параметров, разделяя их пробелами:

./program 10 20 30

В коде обращайтесь к ним через ParamStr(1), ParamStr(2) и т.д. Не забудьте проверить ParamCount, чтобы избежать ошибки выхода за границы массива.

6. Создание универсальной функции для ввода чисел

Чтобы не повторять один и тот же код для проверки ввода, можно написать универсальную функцию. Ниже приведён пример функции, которая:

  • 🔄 Запрашивает ввод, пока пользователь не введёт корректное число.
  • 📏 Поддерживает ограничение диапазона (например, только положительные числа).
  • 💬 Выводит кастомное сообщение об ошибке.
function InputNumber(min, max: integer; prompt, errorMsg: string): integer;

var

num: integer;

inputStr: string;

code: integer;

begin

repeat

write(prompt);

readln(inputStr);

val(inputStr, num, code);

if (code = 0) and (num >= min) and (num <= max) then

Exit(num); // Возвращаем корректное число

writeln(errorMsg);

until false;

end;

Пример использования:

var

age: integer;

begin

age:= InputNumber(1, 120,

'Введите ваш возраст:',

'Ошибка! Возраст должен быть числом от 1 до 120.');

writeln('Вам', age,' лет.');

end.

Для вещественных чисел функцию можно адаптировать, заменив integer на real и убрав проверку диапазона (или изменив её на сравнение с min: real и max: real).

FAQ: Частые вопросы по вводу чисел в Pascal

Почему программа не ждёт ввода и сразу завершается?

Эточная проблема при запуске программ из некоторых IDE (например, Lazarus в режиме отладки). Решения:

  • Добавьте readln в конце программы, чтобы окно не закрывалось.
  • Запускайте программу из командной строки.
  • В Lazarus отключите опцию «Закрывать после завершения» в настройках проекта.
Как ввести массив чисел с клавиатуры?

Используйте цикл for и стандартный readln:

var

arr: array[1..5] of integer;

i: integer;

begin

for i:= 1 to 5 do

begin

write('Введите элемент', i,':');

readln(arr[i]);

end;

end.

Можно ли ввести число в шестнадцатеричном формате?

Да, для этого используйте функцию HexToInt из модуля SysUtils (только в Free Pascal):

uses SysUtils;

var

hexStr: string;

num: integer;

begin

writeln('Введите шестнадцатеричное число:');

readln(hexStr);

num:= HexToInt(hexStr);

writeln('Десятичное значение:', num);

end.

В Turbo Pascal придётся писать собственную функцию преобразования.

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

Используйте проверку ввода с помощью val или обработку исключений (см. раздел 3). Также можно считывать данные как строку, а затем анализировать её:

var

input: string;

isValid: boolean;

i: integer;

begin

readln(input);

isValid:= true;

for i:= 1 to Length(input) do

if not (input[i] in ['0'..'9','-','.']) then

isValid:= false;

if isValid then

val(input, num, code)

else

writeln('Некорректный ввод!');

end.

Почему при вводе большого числа возникает ошибка?

Это происходит из-за переполнения типа данных. Например, integer в Turbo Pascal ограничен диапазоном -32768..32767. Решения:

  • Используйте longint (диапазон -2147483648..2147483647).
  • Для очень больших чисел применяйте тип int64Free Pascal).
  • Используйте строковый ввод и обрабатывайте числа как строки (например, для калькуляторов с большой точностью).