Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ситкин. Информатика. Программирование в DELPHI

.pdf
Скачиваний:
142
Добавлен:
18.07.2019
Размер:
1.49 Mб
Скачать

Защитные конструкции можно строить на основе алгоритмов ветвления и выбора. Разработаем и реализуем алгоритм проверки каждого вводимого с клавиатуры символа на допустимость (рис. 6.1).

начало

0 .. 9

да

 

 

 

 

 

 

 

нет

 

 

 

 

клавиша

да

 

 

 

backspace

 

 

 

 

нет

 

 

 

 

 

 

 

 

 

 

да

минус

да

заменить

на пустой

 

уже есть

 

 

 

 

 

символ

нет

 

нет

 

 

 

 

 

 

 

 

да

запятая

да

заменить

на пустой

 

уже есть

 

 

 

 

символ

нет

 

 

 

 

нет

 

 

 

 

 

 

 

 

 

 

 

заменить

 

 

 

 

на пустой

 

 

 

 

символ

 

 

 

 

конец

 

Рис. 6.1

 

 

 

 

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

ные вводимые символы также не пропечатаются.

71

Реализуем предложенный алгоритм посредством процедуры обработки события OnKeyPress для компонента Edit1. При этом потребу-

ется функция для работы со строкой символов: Pos( символ , стро-

ка ) возвращает номер позиции символа в строке, если указанного символа нет в строке, то возвращает ноль.

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

case Key of // Key код нажатой клавиши

'0'..'9' : ; // реакции на цифру нет после двоеточия пустой оператор

#8: ;

// реакции нет после двоеточия пустой оператор

' ' :

if Pos(' ', Edit1.Text)<>0 then Key:=#0; {если в поле Edit1

позиция минуса отлична от нуля (т.е. минус уже есть), то второй заменяется пу-

стым символом}

',' : if Pos(',', Edit1.Text)<>0 then Key:=#0; {если в поле Edit1

позиция запятой отлична от нуля (т.е. запятая уже есть), то вторая заменяется пустым символом}

else Key:=#0; // любой другой символ (ветвь else) заменяется пустым end; // конец оператора case

end; // конец процедуры

Замечание. Если вводимое число должно быть целым, то запятая является недопустимым символом, соответствующие элементы в блок-схеме и процедуре должны быть удалены.

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

72

написать пользовательскую процедуру проверки на допустимость аб-

страктного (формального) символа из абстрактного (формального)

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

implementation

{$R *.dfm}

procedure Control(var Symbol:char; Pole:string);

begin

case Symbol of

'0'..'9': ; #8: ;

' ': if Pos(' ', Pole)<>0 then Symbol:=#0; ',': if Pos(',', Pole)<>0 then Symbol:=#0; else Symbol:=#0;

end;

end;

procedure TForm1.Edit1KeyPress(Sender:TObject; var Key: Char);

begin

Control(Key, Edit1.Text);

end;

procedure TForm1.Edit2KeyPress(Sender:TObject; var Key: Char);

begin

Control(Key, Edit2.Text);

end;

…………...…

73

Важно отметить, что разработанная нами процедура, запускаясь

на выполнение всякий раз при нажатии клавиши клавиатуры, не

предотвратит следующие ошибки в полях для ввода чисел:

 

 

наличие в поле только знака минуса;

 

 

 

 

 

наличие знака минуса не на первом месте в числе;

 

 

 

оставление поля пустым.

 

 

 

 

 

 

Все эти ошибки в числах также приведут к некорректной работе

приложения при попытке преобразовать строку в число функциями

StrToInt или StrToFloat. Необходимо предотвратить работу этих функ-

ций, если в числе (числах) есть хотя бы одна из указанных ошибок.

Один из способов дополнить процедуру, в которой осуществ-

ляется считывание числовых данных с переводом их из строки в чис-

ло, проверкой наличия одной из трёх указанных выше ошибок. На

рис. 6.2 представлена блок-схема алгоритма такой процедуры в об-

начало

поле ввода x пустое или

щем виде. Если хотя бы одна

 

 

 

 

 

 

 

содержит только минус

из трёх синтаксических оши-

 

или минус не первый

да

 

 

 

 

 

 

 

бок (поэтому связка «или»

 

 

нет

 

между ними) имеет место, то

ввод x

нарушение

пользователь

информируется

синтаксиса x

 

 

 

 

 

 

 

об ошибке, а сама процедура

 

 

некоторые

 

досрочно

завершается.

Тем

вычисления

 

самым предотвращается счи-

с использ-ем х

 

 

 

тывание

числа

с

ошибкой.

вывод ре-

 

Рассмотрим

вариант

про-

зультата

 

 

 

 

 

 

 

 

 

 

граммной

реализации

алго-

конец

Рис. 6.2

ритма. Вернёмся к нашему

компоненту Edit1, который предназначен для ввода вещественного

 

74

 

 

 

 

 

 

числа, значение которого получает переменная, например, x. Мы уже выше разработали для него процедуру обработки события Edit1KeyPress, контролирующую каждый вводимый символ в поле с клавиатуры, но этого недостаточно. Пусть какие-то вычисления с x и

дальнейший вывод результата происходит при наступлении события Button1Click. В соответствии с алгоритмом процедура примет вид

procedure TForm1.Button1Click(Sender: TObject);

var x:real;

begin

if (Edit1.Text='') //если поле Edit1 пустое

or (Edit1.Text=' ') //или в поле Edit1 минус (лишь только минус)

or ((Pos(' ',Edit1.Text)<>0) and (Pos(' ',Edit1.Text)<>1))

{или позиция минуса в поле Edit1 отлична от нуля и отлична от единицы,

что означает, что минус есть и он не первый}

then //то

begin

ShowMessage('нарушение синтаксиса х'); //вывод сообщения

Exit; //досрочное завершение процедуры, остальное пропустится

end;

x:=StrToFloat(Edit1.Text); //считывание из поля Edit1 и преобразов. в x

…………...….//некоторые вычисления с использованием переменной x

Label2.Caption:=FloatToStr…..//вывод результата

end;

Возможен и другой способ. Можно не дополнять процедуру с основными вычислениями проверкой наличия трёх возможных син-

таксических ошибок. Тогда следует при разработке формы установить значение False свойства Enabled командной кнопки Button1 в окне

75

Object Inspector, это значит, что кнопка Button1 будет изначально не-

доступна при запуске формы для исключения начала счёта при пустом поле Edit1. Кнопка должна оставаться таковой, пока в поле Edit1

записано число с синтаксической ошибкой (одной из трёх, что описа-

ны выше). На рис. 6.3 показана соответствующая блок-схема ал-

начало

 

поле ввода x пустое или

горитма

блокировки

кнопки.

 

 

содержит только минус

Этот алгоритм следует отраба-

 

 

или минус не первый

 

 

 

 

 

 

нет

тывать всякий раз, когда со-

 

 

 

 

 

да

 

 

 

 

держимое поля Edit1 изменяет-

 

 

 

 

 

 

 

 

 

 

 

ся, т.е.

происходит

событие

кнопка

 

кнопка

 

недоступна

 

доступна

 

OnChange для компонента Edit1.

 

 

 

 

 

 

 

 

 

 

Процедура обработки этого

конец

 

Рис. 6.3

события примет вид

 

 

 

 

procedure TForm1.Edit1Change(Sender: TObject); begin

if (Edit1.Text='') //если поле Edit1 пустое

or (Edit1.Text=' ') //или в поле Edit1 минус (лишь только минус)

or ((Pos(' ',Edit1.Text)<>0) and (Pos(' ',Edit1.Text)<>1))

{или позиция минуса в поле Edit1 отлична от нуля и отлична от единицы}

then //то

Button1.Enabled:=False //кнопка недоступна

else //иначе

Button1.Enabled:=True //кнопка доступна end;

Эта процедура обработки события Edit1Change даёт достаточный результат только в паре с процедурой обработки события Edit1KeyPress, как и дополненная контролем Button1Click только в паре с Edit1KeyPress.

76

Конструкции контроля процедуры Edit1Change или Button1Click

также целесообразнее оформить в виде пользовательской подпро-

граммы, если компонентов ввода несколько, как это было с процедурой Edit1KeyPress, чтобы несколько раз не писать по сути одно и то же.

Причем такая подпрограмма должна ответить только на один вопрос:

начало

 

строка пустая или со-

есть в переданной ей фактиче-

 

 

 

 

держит только минус

ской строке синтаксическая

 

 

или минус не первый

 

 

 

 

нет

ошибка или нет – два возмож-

 

 

 

 

 

да

 

 

 

 

ных значения. Это значит, что

 

 

 

 

её лучше оформить в виде ло-

функция =

 

функция =

 

true

 

false

 

гической функции. Блок-схема

 

 

 

 

 

 

 

 

 

 

алгоритма такой функции пред-

конец

 

Рис. 6.4

ставлена на рис. 6.4.

 

 

 

 

 

implementation

{$R *.dfm}

function Control2(Stroka:string):boolean;

begin

if (Stroka='') or (Stroka=' ')

or ((Pos(' ', Stroka)<>0) and (Pos(' ', Stroka<>1)) then Control2:=true else Control2:=false;

end;

procedure TForm1.Button1Click(Sender: TObject); var x, y:real;

begin

if Control2(Edit1.Text) then

begin ShowMessage('нарушение синтаксиса х'); Exit; end;

x:=StrToFloat(Edit1.Text);

77

if Control2(Edit2.Text) then

begin ShowMessage('нарушение синтаксиса y'); Exit; end;

y:=StrToFloat(Edit2.Text);

…………...….

Задание

Дополнить проекты предыдущей лабораторной работы кон-

струкциями контроля синтаксиса вводимых данных.

Содержание отчёта

цель работы и полная формулировка задания;

блок-схемы алгоритмов конструкций контроля синтаксиса;

тексты модулей дополненных проектов;

примеры работы приложений с указанием компонентов при наличии в полях ввода данных с синтаксическими ошибками;

выводы по работе.

Последующие проекты должны содержать конструкции кон-

троля вводимых данных предполагаемым пользователем, обеспечи-

вающих корректную работу приложений при любых данных ввода.

Контрольные вопросы

1.С какой целью следует контролировать вводимые данные?

2.Почему, помимо контроля вводимого с клавиатуры символа на до-

пустимость, следует предусматривать и другой контроль, например,

дополнять им процедуру с вычислениями или блокировать кнопку?

3. По какой причине конструкции контроля целесообразно оформлять в виде собственных (пользовательских) подпрограмм? Почему ещё целесообразнее эти подпрограммы поместить в собственный модуль?

78

условие да
оператор S
Рис. 7.1

Лабораторная работа № 7

АЛГОРИТМЫ ПОВТОРЕНИЙ

Цель работы приобретение умений разработки и программной реализации циклических алгоритмов.

Повторяющийся (циклический) алгоритм алгоритм, в котором результат достигается многократным выполнением одних и тех же действий. Однократный проход таких действий называют итерацией.

В программировании возможность реализовать циклические алгоритмы обеспечивается операторами цикла.

Оператор цикла с предварительным условием

Это универсальный оператор цикла, он имеет следующий вид while условие do оператор S

где while и do служебные слова; условие переменная или выра-

жение логического типа; оператор S оператор, называемый телом цикла. Блок-схема алгоритма, реализуемого оператором цикла с предусловием, представлена на рис. 7.1. Перед

нет каждой итерацией определяется значение

условия , пока оно принимает значение True,

выполняется оператор S . Оператор S может быть составным. Т.е. если необходимо, чтобы в цикле выполнялось несколько операторов, то

их необходимо заключить в операторные скобки begin и end. Если условие принимает

значение False с самого начала, то тело цикла не выполнится ни разу.

79

Пример 7.1

 

 

 

 

 

Разработаем алгоритм вычисления значений функции

 

 

 

2

,

x 0

 

 

 

y x

 

 

 

 

x,

 

x 0

 

 

для аргумента x на промежутке от a до b с шагом h и реализуем его.

начало

 

 

 

После ввода левой и правой

 

 

 

 

 

 

 

 

 

 

границ диапазона a и b и шага

ввод

 

 

 

приращения h, аргумент x должен

a, b, h

 

 

 

последовательно принимать зна-

 

 

 

 

 

 

 

 

чения: a, a+h,

a+2h, …, b. Для

x = a

 

 

 

каждого из этих значений вычис-

 

 

 

 

 

 

 

 

ляется значение функции y в за-

x b

нет

 

 

висимости от условия x 0 и, вме-

 

 

 

да

конец

 

 

сте с соответствующим ему зна-

 

 

 

 

 

x < 0

нет

 

 

чением аргумента x, выводится

 

 

 

 

 

 

да

 

 

 

на каждой итерации. После этого

 

 

 

 

 

 

 

 

 

 

значение аргумента x увеличива-

y = x2

y = x

 

 

ется на шаг h и происходит воз-

 

 

 

 

 

 

 

 

вращение к началу цикла. Если

 

 

 

 

значение x не

превысило

b, то

вывод

 

 

 

осуществляется

следующая

ите-

x и у

 

 

 

 

 

 

 

 

 

 

 

 

 

рация, и всё повторяется, пока x

x = x + h

 

 

 

не превысит b. До входа в цикл

 

 

 

 

 

 

 

 

 

 

следует задать

начальное значе-

 

Рис. 7.2

 

 

ние аргумента x=a, от которого в

 

 

 

 

цикле начнёт увеличиваться значение x. Блок-схема алгоритма пред-

ставлена на рис. 7.2, а пример работы приложения на рис. 7.3.

 

80