
- •Д.С.Ситкин
- •Информатика.
- •Программированиевdelphi
- •Лабораторныйпрактикум
- •Содержание
- •Введение
- •Основныепонятияпрограммирования
- •Этапыпрограммирования
- •Средаdelphi.Созданиепростейшегопроекта
- •Формаиеёсвойства
- •Компонентыформыиихсвойства
- •КомпонентLabeledEdit
- •Событиеипроцедураобработкисобытия
- •Пример1.1
- •Компиляцияизапускпроектанаисполнение
- •Структураисохранениепроекта
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Линейныйалгоритм
- •Типыданных
- •Константыипеременные
- •Арифметическиеоперации
- •Правилазаписитиповыхдействий
- •Структурапроцедурыобработкисобытия
- •Пример2.1
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Подпрограммы
- •Классификацияиструктураподпрограмм
- •Механизмработыподпрограммыиобменапараметрами
- •Пример3.1
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Структурамодуля
- •Созданиеиподключениемодуля
- •Пример4.1
- •Условныйоператор.Неполнаяформа
- •Условныйоператор.Полнаяформа
- •IfусловиеthenоператорS1elseоператорS2
- •Пример5.1
- •Пример5.2
- •Операторвыбора
- •Пример5.3
- •Содержаниеотчёта
- •Контрольныевопросы
- •Контрольсинтаксисавводимыхданных
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Алгоритмыповторений
- •Операторцикласпредварительнымусловием
- •Пример7.1
- •Операторцикласпараметром(сосчётчиком)
- •Пример7.2
- •Пример7.3
- •Операторцикласпоследующимусловием
- •Пример7.4
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Массивы
- •Объявлениемассива
- •Обработкамассивов
- •Пример8.1
- •Динамическиемассивы
- •Подпрограммасоткрытымпараметром-массивом
- •Пример8.2
- •Целесообразностьвыделенияпамятиподмассивы
- •Контрольсинтаксисаэлементовмассива
- •Задание
- •Обработкамногомерныхмассивов
- •Пример9.1
- •КомпонентStringGrid
- •Пример9.2
- •Сортировкамассивов
- •Пример9.3
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Внешниефайлы
- •Физическиеилогическиефайлы
- •Классификациялогическихфайлов
- •Процедурыифункцииобработкифайлов
- •Пример 10.1
- •КомпонентыOpenDialog иSaveDialog
- •Пример 10.2
- •Пример 10.3
- •Задание
- •Содержаниеотчёта
- •Контрольныевопросы
- •Олабораторнойработе
- •Информатика. Программированиев delphi
Содержаниеотчёта
цельработыизадание;
длякаждогоизтрёхзаданий:
блок-схемаалгоритмарешения;
текстмодуляпроекта;
примерработыприложениясуказаниемкомпонентов;
выводыпоработе.
Контрольныевопросы
Какойалгоритмназываютразветвляющимся?
Чтотакоелогическоевыражение,каконостроится?
Приведитетаблицуистинностиосновныхлогическихопераций.
Каковсинтаксисполнойинеполнойформусловногооператора?
Чтотакоесоставнойоператор,когдаегоиспользуют?
Какуюконструкциюреализуетзаписьifx=0thenelsey:=1?
Каковсинтаксисоператоравыбораисхемаегоработы?
Вчёмсостоятотличиязависимогопереключателяотфлажка?
Лабораторнаяработа№6
Контрольсинтаксисавводимыхданных
Цель работыприобретение умений построения конструкцийконтролявводимыхчисловыхданных пользователем.
В предыдущих проектах при вводе чисел с компонентов формыприходилось рассчитывать только на аккуратность предполагаемогопользователя. В случае ошибочного наличия в числе недопустимогосимвола (например, буквы) происходит ошибка при попытке преобра-зовать содержимое поля редактированияEditилиLabeledEdit(свойствоText)изстрокивчислофункциямипреобразованияStrToIntилиStrToFloat,чтоможетповлечьаварийнуюостановкуработыприложе-ния.Программист должен предусмотреть возможные некорректныедействияпользователяикорректнуюреакциюприложениянаних.
Предположим, что в проекте на форме расположен компонентEdit1для ввода вещественного числа. К нарушению синтаксиса, а впоследствии невозможности преобразовать в число содержимое поляEdit1.Textприведут:
наличие недопустимых символов в числе (буквы, спецсимво-лы,точка,знаки вопросаиливосклицанияит.п.);
наличиедвухиболеезапятыхилизнаковминуса;
наличиезнакаминусаневначале числа;
отсутствиеданных вполевообще.
Длякорректнойработыприложенияследуетлибоисключитьввод недопустимых символов, либо предотвратить работу функциипреобразованияStrToFloatприналичиисинтаксическихошибоквчис-леисообщитьпользователюоних.
Защитныеконструкцииможностроитьнаосновеалгоритмовветвленияивыбора.Разработаемиреализуемалгоритмпроверкикаждоговводимогосклавиатурысимволанадопустимость(рис.6.1).
К числу допустимых символов отнесеныцифры иразрешеноудаление ошибочного символа (клавишаBackspaceклавиатуры). Еслинажата соответствующая клавиша, то никаких отменяющих действийне последует. Разрешён также ввод знака минуса или запятой приусловии, что аналогичный символ не был уже поставлен, в противномслучае повторный символ заменяется пустым символом. Все осталь-ныевводимыесимволы такженепропечатаются.
Реализуем предложенный алгоритм посредством процедуры об-работки событияOnKeyPressдля компонентаEdit1. При этом потребу-ется функция для работы со строкой символов: Pos(символ,стро-ка)возвращает номер позиции символа в строке, если указанногосимволанет встроке,товозвращаетноль.
procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);
begin
caseKeyof //Keyкоднажатойклавиши
'0'..'9' :;//реакциина цифрунетпоследвоеточияпустойоператор
#8:;//реакциинетпоследвоеточияпустойоператор
'' :ifPos('', Edit1.Text)<>0thenKey:=#0;{если в полеEdit1позиция минуса отлична от нуля (т.е. минус уже есть), то второй заменяется пу-стымсимволом}
',' :ifPos(',', Edit1.Text)<>0thenKey:=#0;{если в полеEdit1позиция запятой отлична от нуля (т.е. запятая уже есть), то вторая заменяетсяпустымсимволом}
elseKey:=#0;//любойдругойсимвол(ветвьelse)заменяетсяпустым
end;//конецоператораcase
end;//конецпроцедуры
Замечание. Если вводимое число должно быть целым, то запятаяявляетсянедопустимымсимволом,соответствующиеэлементывблок-схемеипроцедуредолжныбытьудалены.
Обычнонаформеприсутствуетнесколькокомпонентовдлявводачисел.Всвязисэтимнеобходимонесколькоразпрописыватьпо сути один и тот же текст процедуры контроля синтаксиса, изменяялишь имена компонентов ввода, а объём программного кода при этомзначительновозрастает.Возникаетцелесообразностьоднократно
написать пользовательскую процедуру проверки на допустимость аб-страктного(формального)символаизабстрактного(формального)поля, а затем вызывать эту пользовательскую процедуру в процедурахобработки событияOnKeyPressдля различных компонентов несколькораз,передаваявпользовательскуюпроцедурунапроверкуввидефактическихпараметровконкретныйсимволконкретногополяввода.
implementation
{$R*.dfm}
procedureControl(varSymbol:char;Pole:string);
begin
caseSymbolof
'0'..'9':;
#8:;
'':ifPos('', Pole)<>0thenSymbol:=#0;',':ifPos(',', Pole)<>0thenSymbol:=#0;elseSymbol:=#0;
end;end;
procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);
begin
Control(Key,Edit1.Text);
end;
procedureTForm1.Edit2KeyPress(Sender:TObject;varKey:Char);
begin
Control(Key,Edit2.Text);
end;
…………...…
Важно отметить, что разработанная нами процедура, запускаясьнавыполнениевсякийразпринажатииклавишиклавиатуры,непредотвратитследующиеошибки вполяхдлявводачисел:
наличиевполетолькознакаминуса;
наличиезнакаминусаненапервомместевчисле;
оставлениеполяпустым.
Все эти ошибки в числах также приведут к некорректной работеприложения при попытке преобразовать строку в число функциямиStrToIntилиStrToFloat. Необходимо предотвратить работу этих функ-ций,есливчисле(числах)естьхотябыоднаизуказанныхошибок.
Один из способовдополнить процедуру, в которой осуществ-ляется считывание числовых данных с переводом их из строки в чис-ло,проверкойналичияоднойизтрёхуказанныхвышеошибок.Нарис.6.2представленаблок-схемаалгоритматакойпроцедурывоб-
начало
нет
некоторыевычисления
сиспольз-емх
вводx
выводре-зультата
конец
полевводаxпустоеилисодержиттолькоминус
даилиминуснепервый
нарушениесинтаксисаx
Рис.6.2
щем виде. Если хотя бы однаиз трёх синтаксических оши-бок(поэтомусвязка«или»между ними) имеет место, топользовательинформируетсяоб ошибке, а сама процедурадосрочнозавершается.Темсамымпредотвращаетсясчи-тываниечисласошибкой.Рассмотримвариантпро-граммнойреализацииалго-ритма.Вернёмсякнашему
компонентуEdit1,которыйпредназначендлявводавещественного
числа, значение которого получает переменная, например,x. Мы ужевышеразработалидлянегопроцедуруобработкисобытияEdit1KeyPress, контролирующую каждыйвводимый символ в поле склавиатуры, но этого недостаточно. Пусть какие-то вычисления сxидальнейший вывод результата происходит при наступлении событияButton1Click.Всоответствиисалгоритмомпроцедураприметвид
procedureTForm1.Button1Click(Sender:TObject);
varx: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вокне
ObjectInspector,этозначит,чтокнопкаButton1будетизначальноне-доступна при запуске формы для исключения начала счёта при пу-стом полеEdit1. Кнопка должна оставаться таковой, пока в полеEdit1записано число с синтаксической ошибкой (одной из трёх, что описа-нывыше).Нарис.6.3показанасоответствующаяблок-схемаал-
начало
да
кнопканедоступна
конец
полевводаxпустоеилисодержиттолькоминус
илиминуснепервыйнет
кнопкадоступна
Рис.6.3
горитмаблокировкикнопки.Этот алгоритм следует отраба-тыватьвсякийраз,когдасо-держимое поляEdit1изменяет-ся,т.е.происходитсобытиеOnChangeдля компонентаEdit1.Процедураобработкиэтогособытияпримет вид
procedureTForm1.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.
Конструкции контроля процедурыEdit1ChangeилиButton1Clickтакжецелесообразнееоформитьввидепользовательскойподпро-граммы, если компонентов ввода несколько, как это было с процеду-ройEdit1KeyPress, чтобы несколько раз не писать по сути одно и то же.Причемтакаяподпрограммадолжнаответитьтольконаодинвопрос:
начало
да
функция =true
конец
нет
строка пустая или со-держит только минусилиминуснепервый
функция =false
Рис. 6.4
есть в переданной ей фактиче-скойстрокесинтаксическаяошибка или нет – два возмож-ныхзначения. Этозначит, чтоеё лучше оформить в виде ло-гическойфункции.Блок-схемаалгоритма такой функции пред-ставленанарис.6.4.
implementation
{$R*.dfm}
functionControl2(Stroka:string):boolean;
begin
if(Stroka='')or(Stroka='')
or((Pos('',Stroka)<>0)and(Pos('',Stroka<>1))
thenControl2:=trueelseControl2:=false;
end;
procedureTForm1.Button1Click(Sender:TObject);
varx,y:real;
begin
ifControl2(Edit1.Text)then
beginShowMessage('нарушениесинтаксисах');Exit;end;
x:=StrToFloat(Edit1.Text);
ifControl2(Edit2.Text)then
beginShowMessage('нарушениесинтаксисаy');Exit;end;
y:=StrToFloat(Edit2.Text);
…………...….