Исключительные ситуации

Исключительная (или особая) ситуация представляет собой сигнал о произошедшей в приложении ошибке. Для обработки исключительных ситуаций используются две конструкции:

try try

защищаемый код защищаемый блок

finally except
код завершения обработчик исключения

end; end;

В первом варианте блок finally выполняется независимо от того, возникла ли ошибка в процессе выполнения защищаемых операций.

Блок try except используется для обработки исключитель­ных ситуаций. В Object Pascal исключительные ситуации пред­ставляют собой объекты, содержащие информацию, идентифи­цирующую ошибку и место ее возникновения. Внутри части except создаются обработчики особых ситуаций для классов исключительных ситуаций. Обработчик особой ситуации имеет следующий формат:

try

защищаемый блок except

on E: ESomeException do <обработчик исключениям end;

Для обработки особой ситуации Delphi предоставляет воз­можность создания временных объектов особой ситуации (Е), которые могут использоваться в обработчике исключения. Временный объект особой ситуации имеет тот же тип, что и объект исключения, который он обозначает (ESomeException).

Существуют предопределенные классы исключительных си­туаций для обработки стандартных ошибок, таких, как нехват­ка памяти, деление на нуль, числовое переполнение, ошибки ввода-вывода и другие. Перечислим некоторые из них:

EMathError класс-предок исключений, случающихся при выполнении операций с плавающей точкой;

EInvalidArgument значение параметра выходит за диапазон значений

EInvalidOp передача математическому сопроцессору ошибочной конструкции;

EOverflow переполнение разрядов при работе со слишком большими величинами;

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

EZeroDivide деление на ноль;

EIntError класс-предок исключений, случающихся при выполнении целочисленных операций;

EDivByZero деление на ноль;

EIntOverflow выполнение операций, приводящих к переполнению целых переменных;

ERangeError значение целочисленного выражения выходит за пределы установленного целочисленного типа. Попытка обращения к элементу массива по индексу, выходящему за пределы массива;

EListError обращение к элементу списка (String, List, TStringList) по индексу, выходящему за пределы допустимых значений;

EInOutError ошибки при операциях с файловой системой. Код ошибки возвращается в локальной переменной ErrorCode, которая может принимать следующие значения:

2 файл не найден

3 неверное имя файла

4 слишком много открыто файлов

5 отказ в доступе

100 конец файла

101 диск полон

106 неверная операция ввода;

EConvertErrorошибки преобразования типов (простых, объектных).

Например, для создания устойчивого к ошибкам приложе­ния, записывающего данные в файл, необходимо написать сле­дующий код:

begin

assignfile (f, 'data.dan1); try

append(f); try

writeln(f,s); finally

closefile(f); end; except

on E: EInOutError do if E. ErrorCode = 2 then

if MessageDlg('Файл не найден. Создать его?', mtError, [mbYes, mbNo],0)=mrYes

then FileCreate('data.dan');

end;

end;

В данном листинге внутренний блок try finally используется для того, чтобы файл был закрыт в любом случае, т. е. незави­симо от того, была ошибка или нет.

Внешний блок try except используется для обработки иск­лючительной ситуации, которая может произойти в программе. После закрытия файла во внутреннем блоке finally блок except использует временный объект Е для определения типа произо­шедшей ошибки ввода/вывода.

Упражнение 5.2.1. Модифицируйте приложение, созданное в упр. 5.1.1, так, чтобы при повторном запуске программы дан­ные, введенные в предыдущем сеансе, отображались на страницах блокнота.

Решение

Напишем метод, который все странички блокнота будет со­хранять в отдельных файлах в каталоге, указанном в перемен­ной dir. В разделе public описания класса TNoteBookF опишите метод SaveAll и переменную dir:

public

{ Public declarations } dir: string; procedure SaveAll;

В разделе Implementation модуля опишите программный код метода:

procedure TNoteBookF.SaveAll;

var i: integer;

TempComponent: TListBox; begin

InputQuery('Введите полное имя каталога','',dir);

for i:=0 to 11 do

begin

NoteBookl.Pagelndex:=i; TempComponent:=

TListBox(FindComponent('ListBox'+IntToStr(i+1))); TempComponent.Items.SaveToFile(dir+Month1+intToStr(i + 1));

{Строки компонента ListBox сохраняются в соответствующем файле}

end;

end;

Эксперимент. Сохраните и запустите приложение. Убеди­тесь в работоспособности приложения для существующих ката­логов. Попробуйте сохранить файлы в несуществующий ката­лог, например c:\NoteBook\Month\. ♦

Для несуществующего каталога операционная система воз­буждает исключительную ситуацию, результатом которой ото­бражается сообщение об ошибке, изображенное на рис. 5.2.1: «Приложение Projectl.exe возбудило исключительную ситуа­цию типа EFCreateError с сообщением 'Невозможно создать

файл C:\NoteBook\Month\Monthl1. Процесс остановлен. Вос­пользуйтесь командами Step или Run для продолжения.»

Чтобы обезопасить приложение от подобного вида ошибок, добавим блок обработки исключительной ситуации EFCreateEr­ror (рис. 5.2.1), возникшей при сохранении файла:

begin

InputQuery('Введите полное имя каталога','',dir); if dir[length(dir)]<>'\'

then dir:=dir+'\';

{добавляем разделитель подкаталогов в конец строки}

for i:=0 to 11 do begin

NoteBookl.Pagelndex:=i;

TempComponent:=

TListBox(FindComponent('ListBox'+IntToStr(i+1)));

try

TempComponent.Items.SaveToFile(dir+'Month'+intToStr(i+1)); {Строки компонента ListBox сохраняются в соответствующем файле} except

on EFCreateError do

begin

{класс исключений, возникающих при неудачных попытках

создания файла}

makedir (dir); {процедура создания каталога (смотри ниже)} TempComponent.Items.SaveToFile(dir+'Month'+intToStr(i+1)); end; end; end; end;

Рассмотрим процедуру создания подкаталогов:

procedure MakeDir{dir: string); var d: string;

k: byte; begin

k:=pos('\',dir); d:=copy(dir,1,k); delete(dir,1,k);

{выделяем название корневого каталога из dir, запоминаем в переменной d}

while DirectoryExists(d) do begin

{пока каталог с именем, указанным в переменной d, существует} k:=pos ('\',dir); d:=d+copy(dir,1,k); delete(dir,1,k);

{выделяем имя очередного подкаталога из переменной dir} end;

{в переменной d хранится имя несуществующего каталога} CreateDir(d);

{стандартная функция создания подкаталога с именем d} while (pos('\',dir)<>0) do begin

k:=pos('\',dir); d:=d+copy(dir,1,k); delete(dir,1,k); CreateDir(d); end; end;

Эксперимент. Запустите приложение. Убедитесь, что при вводе неправильного имени каталога происходит обработка исключительной ситуации и создается каталог с заданным именем. ♦

Задания для самостоятельного выполнения

1. Сохранение данных блокнота. При нажатии кнопки 'Закрыть', если были внесены изме­нения в блокноте, появляется диалоговое окно с текстом 'Сохранить изменения?' и двумя кнопками 'Да' и 'Нет'. При нажатии на 'Да' данные сохраняются в файлах, при нажатии на 'Нет' — приложение закрывается без сохране­ния изменений.

2. Модифицируйте код приложения так, чтобы вопрос «Сохра­нить изменения?» появлялся только, если данные блокно­та были изменены.

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

4. Считывание данных в блокнот.

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

b) Создайте модальное окно выбора папки для сохранения (и считывания) данных блокнота. Модифицируйте код прило­жения так, чтобы при запуске появлялось модальное окно для выбора папки, в которой хранятся данные. Примечание. Используйте компоненты DriveComboBox, Directo­ry ListBox, FileListBox, FilterComboBox со страницы Win 3.1 па­литры компонентов.

5. Данные блокнота хранятся в двенадцати файлах — это не яв­ляется рациональным с точки зрения компактности данных. Продумайте структуру файла для хранения записей блокно­ та и внесите необходимые изменения в программный код.

Примечание. Для работы с файловым типом данных в языке Object Pascal используются следующие процедуры:

AssignFile(<файловая переменная>, <имя файла>) — уста­навливает соответствие между внешним файлом и файловой пе­ременной.

Reset (<файловая переменная>) — открывает на чтение существу­ющий внешний файл, ассоциированный с файловой переменной Append (<файловая переменная>) —подготавливает существу­ющий файл, ассоциированный с файловой переменной, для до­бавления записей в конец.

Rewrite {<файловая переменная>) — создает новый файл с именем, соответствующим файловой переменной, и устанавлива­ет его в режим записи элементов.

CloseFile (<файловая переменная>) — разрывает установленное соответствие между файловой переменной и внешним файлом.

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

7. Используя компонент RadioGroup, напишите приложе­ние-тест. Первое окно: приложение предлагает ввести имя тестируемого. Далее даются вопросы теста по одному:

1. В компании кто-то рассказывает историю, которую вы уже слы­шали. Вы

а) улыбаясь, спокойно выслушиваете до конца;

б) отворачиваетесь или выходите из комнаты;

в) слушаете, но всем своим видом выражаете недовольство;

г) перебиваете рассказчика.

2. Кто-то высказывает мнение в корне противоречащее вашему. Вы:

а) выслушиваете и продолжаете заниматься своим делом;

б) стараетесь выйти;

в) говорите, что не желаете обсуждать с ним это;

г) защищаете свои убеждения.

3. Вы считаете, что

а) люди как правило на добро отвечают добром;

б) многие быстро забывают доброе к ним отношение;

в) люди корыстны;

г) многие неблагодарны и пользуются вашим добрым отношением к ним.

4. Настоящий друг

а) помогает тому, кого считает своим другом;

б) старается помочь;

в) в любых ситуациях поддержит;

г) всегда разделяет точку зрения того, кого считает другом.

1. В отношениях лучше, когда

а) никто из партнеров ни от кого не зависит;

б) оба партнера друг от друга во многом зависят;

в) кто-то зависит от вас;

г) вы зависите от партнера, зато он многое берет на себя.

2. Когда кто-то часто допускает речевые ошибки, вы

а) не обращаете внимания;

б) стараетесь лишь изредка поправлять его;

в) предлагаете ему взять уроки русского языка;

г) не можете удержаться от того, чтобы постоянно не поправлять его.

3. Встречаясь с новыми людьми, вы

а) ведете себя естественно;

б) бываете остроумны, чтобы произвести впечатление;

в) стремитесь быть настороже, чтобы ничто не прошло мимо ва­шего внимания;

г) постоянно помните, что подвергаетесь оценке окружающих.

4. Вы

а) любите обсуждать комические ситуации, в которых сами побы­вали;

б) любите когда подшучивают над вами;

в) очень любите подшучивать над другими;

г) не позволяете, чтобы другие подшучивали над вами.

5. Когда вас приглашает в гости кто-то из близких друзей, а вы уже собрались в другое место, то вы

а) говорите об этом;

б) не называете причины отказа;

в) прикидываетесь, что больны;

г) говорите, что у вас работа.

6. Вы считаете совершенно необходимым

а) быть с собой в ладу в любых ситуациях;

б) всегда соответствовать общему духу компании;

в) чтобы окружающие считались с вашим настроением;

г) держаться с достоинством и не показывать своих чувств.

Для перехода на следующий вопрос теста необходимо обяза­тельно выбрать один из предлагаемых ответов. После ответа на последний вопрос теста предлагается интерпретация получен­ного результата:

Если общая сумма ответов «а» составляет 7 и более, то большинст­во людей относятся к вам с симпатией. Умение быть искренним и в то же время не обижать позволяет вам сохранять мир с самыми разными людьми. Вы умеете, оставаясь собой, позволять и другим быть собою. Вы не подстраиваетесь под чужое мнение, но и не требуете к себе осо­бого отношения, проявляя терпимость и способность понять другого. Если общая сумма ответов «б» составляет 7 и более, то у вас, в общем, хорошие отношения с людьми. Вы достаточно терпимы. Иногда, правда, вы слишком «подыгрываете» окружающим, вплоть до неискренности. От этого сами, бывает, чувствуете дискомфорт. Тем не менее вам не чуж­ды прагматизм и некоторое недоверие к окружающим. Поверьте, они это чувствуют.

Если общая сумма ответов «в» составляет 7 и более, то лишь не­многие относятся к вам с симпатией. Со многими у вас возникают проблемы. Вы недостаточно терпимы к окружающим, вас многое раз­дражает. Вы предпочитаете иногда слишком дистанцироваться или, наоборот, чересчур давить на людей, если что-то вам не по вкусу. Ваше недоверие и подозрительность не могут оставаться незамеченны­ми и отталкивают людей.

Если общая сумма ответов «г» составляет 7 и более, то вам никто не симпатизирует.

Если в ваших ответах самые разные варианты, то люди к вам отно­сятся по-разному. Одни — с симпатией, а кому-то вы антипатичны. Но в любом случае, чем больше в ваших ответах вариантов «а», тем боль­ше у вас шансов на взаимопонимание и взаимную симпатию в обще­нии.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: