Возможные пути реализации диалоговых программ

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

Так как в Паскале операторы ввода READ (READLN) не могут содержать поясняющий текст, то для организации простейшего диалога и вывода на экран пояснений необходимо перед оператором ввода в программу вставлять оператор вывода информации WRITE (WRITELN), содержащий текст, поясняю­щий порядок ввода исходных данных.

Пример 1.1. Необходимо в программу ввести значения переменных а, b, X. Операторы, реализующие этот ввод, состоят обычно из двух операторов: оператора вывода WRITE , содержащего в скобках поясняющую текстовую константу, например (‘Введите значения a b X’), и оператора ввода READLN(a,b,X), содержащего список переменных, значения которых необходимо ввести. Эта часть программы будет иметь вид:

WRITE (‘Ввести значения переменных: а b Х ’); {Пояснение ввода}

READLN ( a,b,X); {присваивание значений переменным}

Это простейший диалог, никак не защищенный от ошибок ввода и “зависания” программы при этом. Простейшая ошибка - ввод значений переменных не через пробел (таково требование Паскаля), а через запятую. Чтобы не провоцировать пользователя на эту ошибку, в операторе пояснения ввода Write переменные a b Х следует записывать через пробел, а не через запятую. Другая распространенная ошибка - отделение запятой, а не точкой дробной части числа. К сожалению, простыми средствами от этой ошибки трудно избавиться.

Как избежать подобных ошибок ввода? Прежде всего надо отказаться от использования в операторе ввода READ (READLN) числовых переменных. Единственное, что можно точно сказать о данных, которые пользователь будет вводить, то, что это будет строка символов. Поэтому будем помещать вводимые данные в строковую переменную. В строку можно записать любой символ с клавиатуры и это не будет ошибкой. После этого программа сама может разобраться с правильностью введенной пользователем информации. При этом целесообразно проверить нахождение введенного значения в заданном диапазоне.

Возможны по крайней мере два варианта построения подобных диалоговых программ. Первый вариант использует оператор ввода READLN с переменной строкового типа. Число вводится в виде строковой символьной последовательности, поэтому программа примет любой их набор. После окончания ввода (нажатия клавиши Enter) проводится проверка введенной последовательности на недопустимые символы. Для этого организуется цикл перебора от 1 до N = Length (<строчная переменная>), где Length - функция определения числа символов в строке. При переборе символов строки (строковая функция Copy) каждый символ последовательно сравнивается (используя функцию Pos) со строкой допустимых символов и, если встретится недопустимый символ, то функция принимает значение, равное нулю, и это явится сигналом для повторного ввода последовательности данных. Если проверка показала, что введены только допустимые символы, то происходит преобразование введенной строки с помощью функции Val в число.

Ниже приведена программа, реализующая этот принцип.

Пример 1.2.Проверка строки на числовое содержимое.

Составить программу ввода числа часов (0 - 24).

Допустим ввод только числовых знаков.

Program Wwod_hours1;

Label 1,2;

Var

hou,hours:string[3]; err,er,i,h,hour_istina:integer;

BEGIN

2: er:=0;

Write(‘Введите число часов в диапазоне 0..24 ’);

Readln(hours); {Ввод числа часов в виде строки}

hou := ‘’;

For i := 1 to length(hours) do {Определение длины числа}

Begin

If pos((copy(hours,i,1)),’0123456789') = 0 Then

{ Здесь используются две строковые функции: Сору -для поочередного }

{ выделения символов из введенной строки и затем Pos - для }

{ проверки каждого выделенного символа со списком допустимых }

{ символов, представленных в виде строки ‘0123456789’ }

Begin

er:=1; {Признак ошибочного символа}

Goto 1;

End

Else

Begin

hou := hou + copy(hours,i,1);

Writeln(hou);

End;

1: End;

Val(hou,hour_istina,err); {Val - функция преобразования строки в число}

if er=1 Then

Begin

Writeln(‘Ошибка при вводе символа! Повторите ввод ! ‘);

Goto 2;

End

Else If hour_istina <= 24 {Проверка величины числа}

Then

Writeln(‘Чac равен ‘,hour_istina)

Else

Begin

Writeln(‘Чac > 24 ‘,’Повторите ввод !’);

Goto 2 {Переход на повторный ввод данных}

End

END.

Строки вывода исходных данных и результатов должны иметь понятные пояснения выводимых величин, при этом если выводятся значения вещественного типа, то выводимая переменная должна иметь соответствующий формат, в котором указывается общее количество символов в числе, включая знак и точку, и число знаков после запятой (например, а:7:2).

Второй вариант (см. пример 1.3) использует для ввода функцию опроса клавиатуры ReadKey из стандартного модуля Crt (подробнее об этом модуле см. ниже), которая приобретает значение кода последней нажатой клавиши. Таким образом, программа работает в темпе нажатия клавиш пользователем, пока идут обращения к ReadKey. Затем в теле цикла код нажатой клавиши сравнивается с допустимыми кодами клавиш. Символы, соответствующие кодам нажатых клавиш, суммируются, образуя строку введенного числа. Если нажата клавиша с недопустимым символом, то этот символ игнорируется и не попадает в результирующую строку. Однако программе при этом целесообразно подать пользователю краткий звуковой сигнал, информирующий его о неправильно нажатой клавише (клавиша с недопустимым кодом). Когда набор значения параметра заканчивается, пользователь нажимает Enter и содержимое строки преобразуется в число с помощью процедуры Val.

Пример 1.3.Проверка строки на числовое содержимое.

Составить программу ввода числа часов (0 - 24).

Использовать для ввода функцию ReadKey.

Program Wwod_hours2;

Uses Crt; {Подключение модуля управления экраном}

Label 2;

Var

ho:Char;

hours:String[2];

err,i,hour_istina:lnteger;

BEGIN

2: Write (‘Введите число часов в диапазоне 0..24 ‘);

hours:=”;i:=0;

{Начало цикла ввода}

Repeat ho := ReadKey; {Считывание кода нажатой клавиши}

If (ho > #47) And (ho < #58) Then {Коды цифр от 0 до 9}

Begin

Write(ho); {Вывод символа на экран (эхо-печать)}

i:=i+1; {Подсчет введенных символов}

hours:= hours + ho; {Накопление строки ввода}

End

Else If ho <> #13 Then {Код#13 - код клавиши Enter}

Write(#7); {Подача звукового сигнала при вводе ошиб. символа}

Until (ho = #13) Or (i = 2); {Ввод символов продолжается, пока не нажата}

{клавиша Enter или число введенных символов = 2}

Writeln;

Val(hours,hour_istina,err); {Получение из строки hours числа}

If hour_istina <= 24 {Проверка на максимальную величину}

Then Writeln(‘Час равен ‘,hour_istina)

Else Begin Writeln(‘Час > 24 ‘.’Повторите ввод !’);

Goto 2

End

END.

Необходимо дать некоторые пояснения к использованию функций опроса клавиатуры ReadKey и KeyPressed. Символы, вводимые с помощью функции ReadKey, при нажатии клавиш никогда не отражаются на дисплее, т.е. ввод символов происходит вслепую. Поэтому для контроля введенных символов необходимо использовать специальную последовательность операторов, реализующих функцию эхо-печати (см. пример 1.3).

Функция KeyPressed возвращает логическое значение True, если в буфере ввода с клавиатуры имеется хотя бы один символ (т.е. была нажата какая-либо клавиша), и False, если буфер пуст. Для ее использования можно применить конструкцию:

If KeyPressed then <действие> else <действие>;

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

Примечание. Если необходимо ввести в программу вещественное число со знаком, то проверка кодов вводимых символов может быть выполнена с использованием такого фрагмента:

Repeat ho := ReadKey; {Считывание кода нажатой клавиши}

If (ho > #47) And (ho < #58) Or {“Если цифра или...}

(ho=#46) And Perv Or {...точка-впервые или...}

(ho = #45) And (i =0) Then {... минус в 1-й позиции...}

Begin

i := i+1;

hours := hours + ho; {...то заполняется строка hours”}

If ho = #46 Then Perv := False; {если есть вторая точка}

Write(ho) {Вывод символа на экран}

End;

Приведенные выше примеры - простейшая иллюстрация ввода данных с контролем на недопустимые символы и вывода результатов в понятной форме.

Наши рекомендации