Содержание
Задача: Составить программу деления вещественных чисел. программа должна выполнять обработку исключений c использованием конструкции try … catch
, и выдавать следующие сообщения о характере ошибки:
- не введено число (с помощью оператора условия);
- введено слишком длинное число (с помощью оператора условия);
- деление на ноль;
- ошибка преобразования.
Неопределенности задачи
В целом, условия задачи полностью понятны за исключением одного — кто решает, что введено слишком длинное число? Мы, как разработчики программы, можем самостоятельно ввести ограничение, а можем при решении задачи отталкиваться от пределов значение типа long
и отлавливать исключение, используя стандартный тип исключения. Учитывая, что в задаче сказано «длинное», а не «большое» или «маленькое», то ориентироваться будем на первый вариант работы — сами обозначим в программе «максимальную длину числа».
Типы исключений, используемые в программе
В целом, программа будет отрабатывать четыре типа исключений:
System.FormatException
— исключение, возникающее в том случае, если строка не может быть преобразована в числоSystem.DivideByZeroException
— исключение, возникающее при попытке деления на ноль- третье и четвертое исключение — возникающее, когда введено «длинное» число или число не введено, в принципе. Здесь мы можем как определить свои типы исключений, так и воспользоваться базовым классом
Exception
. Далее будут рассмотрены оба варианта.
Решение лабораторной работы
Использование базового класса Exception для обработки исключений
Ниже представлен код программы, в котором мы используем базовый тип исключений Exception
для обработки исключений, когда введено слишком длинное число или число вовсе не введено:
using System; namespace LabRab_3 { class Program { static double ParseString(string str) { byte maxLength = 20; //максимальная длина строки для преобразования. Соответствует значению типа long (-9223372036854775808) if ((str == null) || (str == string.Empty)) throw new Exception("Не введено число"); if (str.Length>maxLength) throw new Exception("Введено слишком длинное число"); return double.Parse(str); } static void Main(string[] args) { try { Console.WriteLine("Введите первое число и нажмите Enter:"); double first = ParseString(Console.ReadLine()); Console.WriteLine("Введите второе число и нажмите Enter:"); double second = ParseString(Console.ReadLine()); Console.WriteLine(first / second); } catch (FormatException) { Console.WriteLine("ошибка преобразования"); } catch (DivideByZeroException) { Console.WriteLine("деление на ноль"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }
Здесь мы в методе ParseString
обрабатываем полученную на входе (в параметрах) строку и, если обнаруживаем, что строка пустая или же, слишком длинная, то возбуждаем исключение типа Exception
в тексте которого сообщаем, что собственно произошло. При этом, системное исключение типа FormatException
будет возбуждено в момент, когда мы попытаемся получить из строки число, используя метод Parse()
. Длина строки контролируется путем сравнения её с переменной maxLength
.
В основной программе мы используем блок try...catch
и фильтруем исключения. При этом, обратите внимание на порядок следования блоков catch
— наиболее общий тип исключения (Exception
) располагается в самом конце. Если попытаться перенести его выше, то программа просто не скомпилируется. Также, при получении исключения типа Exception нам необходимо обязательно «поймать» сам объект исключения ex
, иначе мы не сможем вывести пользователю конкретный текст ошибки.
Результат работы программы без возникновения исключений:
1
Введите второе число и нажмите Enter:
1,11
0,9009009009009008
Результат работы программы, когда введено слишком длинное число:
1
Введите второе число и нажмите Enter:
111111111111111111111111111111111111
Введено слишком длинное число
Использование наследников Exception для обработки своих исключений
Второй вариант выполнения лабораторной работы немного длиннее, так как нам потребуется создать два новых класса-наследника для обработки исключений, но, при этом, программа становится более наглядной:
using System; namespace LabRab_3 { class EmptyStringException : Exception { public EmptyStringException() : base() { } } class VeryLongNumberException : Exception { public VeryLongNumberException() : base() { } } class Program { static double ParseString(string str) { byte maxLength = 20; //максимальная длина строки для преобразования. Соответствует значению типа long (-9223372036854775808) if ((str == null) || (str == string.Empty)) throw new EmptyStringException();//"Не введено число" if (str.Length>maxLength) throw new VeryLongNumberException();//"Введено слишком длинное число" return double.Parse(str); } static void Main(string[] args) { try { Console.WriteLine("Введите первое число и нажмите Enter:"); double first = ParseString(Console.ReadLine()); Console.WriteLine("Введите второе число и нажмите Enter:"); double second = ParseString(Console.ReadLine()); Console.WriteLine(first / second); } catch (FormatException) { Console.WriteLine("ошибка преобразования"); } catch (DivideByZeroException) { Console.WriteLine("деление на ноль"); } catch (EmptyStringException) { Console.WriteLine("Не введено число"); } catch (VeryLongNumberException) { Console.WriteLine("Введено слишком длинное число"); } } } }
Здесь мы объявили своих наследников класса Exception
— EmptyStringException
и VeryLongNumberException
, что позволило нам сделать программу немного удобнее в плане чтения, так как по блоку try...catch
можно сразу отследить все четыре типа исключений и, при необходимости, их обработать.
Результат работы программы будет точно такой же, как и в первом случае.
Итого
Выполняя лабораторную работу мы научились обрабатывать исключения, а также создавать свои собственные типы исключений, возбуждать эти исключения и обрабатывать, используя блок try..catch
.