Программирование с C++ Builder



Ошибки времени выполнения



Во время работы приложения могут возникать ошибки, которые называются ошибками времени выполнения (run time errors) или исключениями (exceptions). В большинстве случаев причинами исключений являются неверные исходные данные.

Например, если во время работы программы вычисления силы тока в поле Напряжение ввести ю.5, т. е. разделить целую и дробную часть точкой, то в результате щелчка на кнопке Вычислить на экране появится окно с сообщением об ошибке (рис. 2.34).



Рис. 2.34. Пример окна с сообщением об ошибке времени выполнения (программа запущена из Windows)


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

Если в настройке Windows указано, что разделитель целой и дробной частей числа — запятая (для России это стандартная установка), а пользователь использовал точку (ввел в поле Напряжение (Edit1) строку 10.5), то при выполнении инструкции

u = StrToFloat(Editl->Text);

возникнет исключение, т. к. при указанной настройке Windows содержимое поля редактирования и, следовательно, аргумент функции StrToFloat не является изображением дробного числа.

Если программа запущена из среды разработки, то при возникновении исключения выполнение программы приостанавливается и на экране появляется окно с сообщением об ошибке и ее типе. В качестве примера на рис. 2.35 приведено окно сообщения о возникновении исключения, причина которого заключается в том, что строка, введенная пользователем в поле редактирования, не является дробным числом.



Рис. 2.35. Пример сообщения о возникновении исключения (программа запущена из C++ Builder)


После возникновения исключения и щелчка на кнопке ОК в диалоговом окне Debugger Exception Notification (рис. 2.35) выполнение программы можно прервать или, несмотря на возникшую ошибку, продолжить. Чтобы прервать выполнение программы, надо в меню Run выбрать команду Program Reset, чтобы продолжить — команду Step Over.

Обработку исключений берет на себя автоматически добавляемый в выполняемую программу код, который обеспечивает, в том числе, и вывод информационного сообщения. Вместе с тем C++ Builder дает возможность программе самой выполнить обработку исключения.

Инструкция обработки исключения выглядит так:

try
{
// здесь инструкции, выполнение которых может вызвать исключение
}
catch ( Тип &е)
{
// здесь инструкции обработки исключения
}

где:

  • try — ключевое слово, обозначающее, что далее следуют инструкции, при выполнении которых возможно возникновение исключений, и что обработку этих исключений берет на себя программа;
  • catch — ключевое слово, обозначающее начало секции обработки исключения. Инструкции этой секции будут выполнены, если в программе возникнет исключение указанного типа.


Основной характеристикой исключения является его тип. В табл. 2.12 перечислены наиболее часто возникающие исключения и указаны причины, которые могут привести к их возникновению.

Таблица 2.12. Типичные исключения


Исключение

Возникает

EConvertError — ошибка преобразования

При выполнении преобразования, если преобразуемая величина не может быть приведена к требуемому типу. Наиболее часто возникает при преобразовании строки символов в число

EDivByZero — целочисленное деление на ноль

При выполнении операции целочисленного деления, если делитель равен нулю

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

При выполнении операции деления над дробными операндами, если делитель равен нулю

EInOutError — ошибка ввода/вывода

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


В программе вычисления силы тока исключения могут возникнуть при выполнении преобразования строк, введенных в поля редактирования, в числа и при вычислении величины тока. Исключение EConvertError возникнет, если пользователь неправильно введет числа в поля редактирования: например, разделит целую и дробную части точкой. Исключение EZeroDivide возникнет, если пользователь задаст величину сопротивления равной нулю. В листинге 2.3 приведена функция обработки события Onclick на командной кнопке Вычислить. В функцию включены инструкции обработки исключений.

Листинг 2.3. Обработка исключений

void __fastcall TForml::ButtonlClick(TObject *Sender)
{
float u; // напряжение
float r; // сопротивление
float i; // ток
// получить данные из полей ввода
// возможно исключение — ошибка преобразования строки в число
try
{
u = StrToFloat(Editl->Text); г = StrToFloat(Edit2->Text);
}
catch (EConvertError &e)
(
ShowMessage("При вводе дробных чисел используйте запятую.");
return;
}
// вычислить ток
// возможно исключение — деление на ноль
try
{
i = u/r;
}
catch (EZeroDivide &e)
{
ShowMessage("Величина сопротивления не должна быть равна нулю");
Edit2->SetFocus(); // курсор а поле Сопротивление
return; }
// вывести результат в поле метки
Label4->Caption = "Ток : " + FloatToStrF(i,ffGeneral,7,3);
}

В приведенной функции для вывода сообщений в случае возникновения исключений использована функция ShowMessage, которая выводит на экран окно с текстом и командной кнопкой ОК. Инструкция вызова функции ShowMessage выглядит так: ShowMessage(Сообщение) ;

Где сообщение — строковая константа (текст, который надо вывести). На рис. 2.36 приведен вид окна сообщения, полученного в результате выполнения инструкции: ShowMessage("Величина сопротивления не должна быть равна нулю.");



Рис. 2.36. Сообщение, выведенное функцией ShowMessage


Следует обратить внимание на то, что в заголовке окна сообщения, выводимого функцией ShowMessage, указывается название приложения. Название приложения задается на вкладке Application окна Project Options. Если название приложения не задано, то в заголовке будет имя исполняемого файла.

Для вывода сообщений можно использовать функцию MessageDig. Функция MessageDig позволяет поместить в окно с сообщением один из стандартных значков, например "Внимание", задать количество и тип командных кнопок и определить, какую из кнопок нажал пользователь. На рис. 2.37 приведено окно, выведенное в результате выполнения инструкции

MessageDig("Файл c:\Xtemp\\test.txt будет удален.",
mtWarning, TMsgDlgButtons() « mbOK « mbCancel, 0);



Рис. 2.37. Пример окна сообщения


Значение функции MessageDig — число, проверив значение которого можно определить, выбором какой командной кнопки был завершен диалог. В общем виде обращение к функции MessageDig выглядит так:

Выбор:= MessageDig(Сообщение, Тип, Кнопки, КонтекстСправки)

где:

  • сообщение — текст сообщения;
  • Тип — тип сообщения. Сообщение может быть информационным, предупреждающим или сообщением о критической ошибке. Каждому типу сообщения соответствует определенный значок. Тип сообщения задается именованной константой (табл. 2.13);
  • кнопки — кнопки, отображаемые в окне сообщения. Задаются операцией включения в множество элементов — констант (табл. 2.14).
  • контекстСправки — параметр, который определяет раздел справочной информации, который появится на экране, если пользователь нажмет клавишу <F1>. Если вывод справочной информации не предусмотрен, то значение параметра должно быть равно нулю.


Таблица 2.13. Константы, определяющие тип сообщения


Константа

Тип сообщения

Значок

mtWarning

Внимание



mtError

Ошибка



mtlnformation

Информация



mtConfirmation

Подтверждение



MtCustom

Обычное

Без значка


Таблица 2.14. Константы, определяющие кнопки в окне сообщения


Константа

Кнопка

Константа

Кнопка

mbYes

Yes

mbAbort

Abort

mbNo

No

mbRetry

Retry

mbOK

OK

mblgnore

Ignore

mbCancel

Cancel

mbAll

All

mbHelp

Help
   


Кроме приведенных констант можно использовать константы mbOkCancel, mbYesNoCancel и mbAbortRetryignore. Эти константы определяют наиболее часто используемые в диалоговых окнах комбинации командных кнопок.

Значение, возвращаемое функцией MessageDig (табл. 2.15), позволяет определить, какая из командных кнопок была нажата пользователем.

Таблица 2.15. Значения функции MessageDlg


Значение функции MessageDlg

Диалог завершен нажатием кнопки

mr Abort

Abort

mrYes

Yes

mrOk

Ok

mrRetry

Retry

mrNo

No

mrCancel

Cancel

mrlgnore

Ignore

mrAll

All