Перейти к содержимому

Try catch c как поймать любое исключение

  • автор:

Как обрабатывать исключения в С++: что такое throw, try и catch

При выполнении кода на C++ могут возникать разные ошибки, которые не позволяют программе выполнять свою работу. Для работы с ошибками или исключениями в C++ используются ключевые слова try , catch и throw .

Детям из Мариуполя нужно 120 ноутбуков для обучения — подари старое «железо», пусть оно работает на будущее Украины

Содержание статьи:

Курс Проджект-менеджмент в IT.

Навчайся у найкращих, курс проводить Тарас Федорук, найкращий PM за версією Ukrainian IT Awards у 2019 році.

Вступление: виды исключений и знакомство с try, catch и throw в C++

Есть два вида исключений, с которыми вы можете столкнуться в процессе:

  1. Синхронные исключения. Этот тип ошибок программа может контролировать сама. Например, ошибки в коде, допущенные программистом или неправильные параметры ввода.
  2. Асинхронные исключения. Этот тип ошибок не связан напрямую с кодом и программа не может их контролировать. Например, это может быть сбой диска, ошибка при открытии файла, сокета, выделения блока памяти.

Когда происходит какое-то событие, прерывающее нормальное функционирование программы, C ++ обычно останавливается и выдает сообщение об ошибке. Когда это происходит, говорят, что C++ выбрасывает ошибку — throw an exception. Мы уже упоминали, что для работы с ошибками или исключениями в C++ используются определенные ключевые слова, давайте познакомимся с ними поближе:

Курс Англійської.
Онлайн-навчання англійської за методикою Кембриджу — вибір понад мільярда людей.

  • try : позволяет определить блок кода, который будет проверяться на наличие ошибок во время его выполнения;
  • throw : нужен для создания и отображения исключений и используется для перечисления ошибок, которые генерирует функция, но не может самостоятельно обрабатывать исключения;
  • catch — блок кода, который выполняется при возникновенииопределенного исключения в блоке try .

Давайте посмотрим, как выглядит пример кода в С++ с использованием try catch и throw :

try < int age = 15; if (age >= 18) < cout else < throw (age); >> catch (int myNum)

Вкратце объясним, как работают операторы try и catch в С++ на примере этого блока . Мы используем блок try для тестирования определенных строк кода: если переменная age меньше 18, мы генерируем исключение и обрабатываем его в блоке catch .

С помощью catch мы перехватываем ошибку и прописываем способ ее обработки. Оператор принимает параметр: в примере используется переменная типа int myNum для вывода значения возраста.

Если все данные соответствуют установленным параметрам, то ошибки не возникает. Например, если указанный возраст будет больше 18, а не 15, как указано в примере, то блок catch просто пропускается.

Если ошибка присутствует, то оператор throw выбросит ошибку. В throw можно прописать любое значение и оператор может выдать текст с пояснением, например:

Access denied - You must be at least 18 years old. Age is: 15

Или установить числовое значение, например, то код ошибки будет выглядеть следующим образом:

Access denied - You must be at least 18 years old. Error number: 505

После такой большой вводной части подробно рассмотрим генерацию исключений и как их обрабатывать, примеры использования try и catch в С++, подробно расскажем про задачи операторов.

Курс Англійської.

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

Генерируем исключения в C++

Исключения могут быть выброшены в любом месте кода. Для этого в блоке нужно прописать throw .

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

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

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

Здесь возникают основные проблемы с обработкой ошибок при использовании оператора if :

  • Все задействованные функции должны возвращать одни и те же типы данных, например, целые числа. Из-за этого код становится длинным и громоздким, потому что приходится возвращать один и тот же вид данных.
  • Глобальную переменную нужно проверить сразу же после вызова функции в обработчике или кэшировать. Потому что она может обновиться, если в дальнейшем произойдет другая ошибка.
  • Обработка ошибки зависит от вызывающей стороны. Если исключение не обработать, оно может вызвать сбой в программе позже или программа продолжит работу неправильно.

Вот так выглядит обработка ошибок в коде при использовании оператора if :

unsigned int error_type = 0; int add(int a, int b) < if (a >100 || b > 100) < error_type = 1; return -1; >else if (a < 0 || b < 0) < error_type = 2; return -1; >return a + b; > int add_wrapper(int a, int b) < return add(a, b); >int main(int, char**) < if (add_wrapper(-1, 8) < 0) < if (error_type == 1) < std::cout else < std::cout = 0" > else < std::cout << "add operation succeeded" return 0; >

А вот так будет выглядеть код с использованием try и catch в С++ (example):

#include using namespace std; class Test < public: Test() < cout ~Test() < cout >; int main() < try < Test t1; throw 10; >catch (int i) < cout >

По сравнению с несколькими строками кода в случае try и catch в С++ , предыдущий блок выглядит очень перегруженным и длинным. В целом при использовании оператора if обработка ошибок и программный код тесно взаимосвязаны. Из-за этого код становится беспорядочным, и трудно гарантировать, что все ошибки будут обработаны и программа будет работать нормально.

Метод try / catch , в свою очередь, обеспечивает четкое разделение между кодом, который знает об ошибке, и кодом, который знает, как обрабатывать ошибку. Таким образом, код, который находятся между этими операторами, может безопасно игнорировать ошибку.

Поэтому, запуская код в С++ Builder, лучше искать исключения с помощью try , catch и throw . Это сделает ваш код проще, чище и с меньшей вероятностью вы допустите ошибки в программе.

Ищем ошибки в коде

Для того чтобы проверить блок кода на ошибки и аномалии, используется оператор try . Так мы можем быть уверены, что если появится исключение в этой части кода, то try его заметит. Главная особенность оператора в том, что в отличие от if / else , которые смешиваются с обычным потоком данных, try отделяет обработку ошибок от обычного течения программы.

Блок try помещается вокруг кода, который может генерировать исключение, и закрывается другим оператором этой пары — catch . Код в блоке try / catch называется защищенным кодом , а синтаксис для использования связки этих операторов выглядит следующим образом:

try < // protected code >catch( ExceptionName e1 ) < // catch block >catch( ExceptionName e2 ) < // catch block >catch( ExceptionName eN ) < // catch block >

С помощью метода try / catch можно перечислить и поймать сразу несколько видов исключений, если блок try вызывает несколько типов ошибок в разных ситуациях. Несмотря на то, что функция может генерировать множество исключений, вы можете обрабатывать не все, а только некоторые из них.

Обрабатываем ошибки с try и catch in С++

Блок catch , идущий в паре с оператором try , ловит и обрабатывает исключения. Чтобы указать, какой тип исключения вы хотите поймать и обработать, нужно прописать это в скобках после ключевого слова catch :

try < // protected code >catch( ExceptionName e ) < // code to handle ExceptionName exception >

Приведенный выше код перехватит только исключение типа ExceptionName . Если вы хотите указать, что блок catch должен обрабатывать любой тип ошибок, который находит оператор try , просто поместите многоточие . между скобками:

try < // protected code >catch(. ) < // code to handle any exception >

Рассмотрим пример кода, в котором генерируется исключение деления на ноль:

#include using namespace std; double division(int a, int b) < if( b == 0 ) < throw "Division by zero condition!"; >return (a/b); > int main () < int x = 50; int y = 0; double z = 0; try < z = division(x, y); cout catch (const char* msg) < cerr return 0; >

Так как программа вызывает тип исключения const char * , в блоке catch необходимо указать const char * , чтобы ошибку можно было определить и обработать. Если скомпилировать и запустить этот блок кода, то в результате получим условие прописанное в throw :

Division by zero condition!

Как работают throw, try и catch в C++: примеры

Рассмотрим на примерах, как между собой взаимодействуют операторы throw , try и catch в С++. В блоке кода ниже приведен простой пример, демонстрирующий обработку исключений. Результат программы наглядно покажет, в какой последовательности происходит выполнение операторов :

#include using namespace std; int main() < int x = -1; // Some code cout > catch (int x ) < cout cout

В результате получается следующая последовательность:

Before try Inside try Exception Caught After catch (Will be executed)

Нужно не забывать прописывать одинаковые типы исключений в try / catch . Если исключение одного типа будет выброшено, а catch не сможет его поймать и обработать, то программа завершается ненормально:

#include using namespace std; int main() < try < throw 'a'; >catch (int x) < cout return 0; >

В этом примере кода исключение является символом, но блок catch для захвата символа отсутствует. В результате блок вернет нам не исключение, а вот такое предупреждение:

terminate called after throwing an instance of 'char' This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

С помощью try / catch можно указывать кастомные типы исключений, наследуя и переопределяя функциональность класса исключений. В примере ниже приведем код, который покажет, как вы можете использовать класс std :: exception для генерации собственной ошибки стандартным способом :

#include #include using namespace std; struct MyException : public exception < const char * what () const throw () < return "C++ Exception"; >>; int main() < try < throw MyException(); >catch(MyException& e) < std::cout catch(std::exception& e) < //Other errors >>

Результат выполнения кода выглядит так:

MyException caught C++ Exception

Еще немного о порядке обработке ошибок в C++

Когда мы прописываем операторы try / catch в коде, то исключение выбрасывается только при исполнении определенных условий. Рассмотрим как работают try , catch и throw в С++ на примере:

#include // for sqrt() function #include int main() < std::cout ; std::cin >> x; try // Ищет исключения в блоке и направляет их к обработчику catch < // этот блок сработает, если пользователь ввел отрицательное число if (x < 0.0) throw "Can not take sqrt of negative number"; // throw выбрасывает исключение типа const char* // Если пользователь ввел число больше 0, то выполняется этот блок кода std::cout catch (const char* exception) // обработчик исключений типа const char* < std::cerr >

Пользователь может ввести число больше нуля, как и задумано. Тогда программа просто продолжит работать в нормальном режиме и пропустит блок с оператором catch . Допустим, пользователь ввел число 49. Тогда результат выполнения кода будет следующим:

Enter a number: 49 The sqrt of 49 is 7

Но пользователи не всегда действуют так, как задумывал разработчик. Поэтому оператор catch нужен нам для того, чтобы программа не сломалась от непредвиденных значений, а могла нормально функционировать и дальше. Поэтому если пользователь введет число меньше нуля, то после того, как try обнаружит непредусмотренное значение, заработают операторы catch и throw , и программа выдаст такое значение:

Enter a number: -4 Error: Can not take sqrt of negative number

Таким образом, строки кода с catch и throw выполняются только тогда, когда try обнаруживает исключение в коде. Если все данные удовлетворяют условиям кода, то блок с исключениями просто пропускается программой.

Подводим итоги

Как использовать try , catch и throw в С++, мы разобрались. Теперь кратко напомним, зачем все это нужно:

  • В первую очередь, код с try / catch занимает меньше строк и легче читается. Блоков с операторами if / else может быть очень много и они будут повторяться, тогда как try / catch содержит только два блока.
  • Исключения C++ заставляют код определять условия ошибки и обрабатывать исключения. Это позволяет не останавливать выполнение программы.
  • После обнаружения исключения код на C++ перестает считывать объекты в блоке кода, сокращая использование программных ресурсов.
  • Получение понятного сообщения об ошибке сильно упрощает процесс исправления бага. Особенно это полезно в случае, если исключение выбрасывается не из-за написанного кода, а, к примеру, из-за использованной библиотеки.
  • Типы ошибок в C++ можно группировать вместе, что позволяет создавать иерархию объектов исключений, группировать их по именам, классам и категоризировать по виду.

Видео: С++ try catch. Обработка исключений С++. Try catch: что это. Изучение С++ для начинающих

Урок №182. Обработка исключений. Операторы throw, try и catch

На предыдущем уроке мы говорили о необходимости и пользе исключений. Исключения в языке C++ реализованы с помощью трех ключевых слов, которые работают в связке друг с другом: throw, try и catch.

Оглавление:

  1. Генерация исключений
  2. Поиск исключений
  3. Обработка исключений
  4. Использование throw, try и catch вместе
  5. Резюмируем
  6. Исключения обрабатываются немедленно
  7. Еще один пример
  8. Что обычно делают блоки catch?

Генерация исключений

Мы постоянно используем сигналы в реальной жизни для обозначения того, что произошли определенные события. Например, во время игры в баскетбол, если игрок совершил серьезный фол, то арбитр свистит, и игра останавливается. Затем идет штрафной бросок. Как только штрафной бросок выполнен, игра возобновляется.

В языке C++ оператор throw используется для сигнализирования о возникновении исключения или ошибки (аналогия тому, когда свистит арбитр). Сигнализирование о том, что произошло исключение, называется генерацией исключения (или «выбрасыванием исключения»).

Для использования оператора throw применяется ключевое слово throw, а за ним указывается значение любого типа данных, которое вы хотите задействовать, чтобы сигнализировать об ошибке. Как правило, этим значением является код ошибки, описание проблемы или настраиваемый класс-исключение. Например:

throw — 1 ; // генерация исключения типа int
throw ENUM_INVALID_INDEX ; // генерация исключения типа enum

throw «Can not take square root of negative number» ; // генерация исключения типа const char* (строка C-style)

throw dX ; // генерация исключения типа double (переменная типа double, которая была определена ранее)

throw MyException ( «Fatal Error» ) ; // генерация исключения с использованием объекта класса MyException

Каждая из этих строк сигнализирует о том, что возникла какая-то ошибка, которую нужно обработать.

Поиск исключений

Выбрасывание исключений — это лишь одна часть процесса обработки исключений. Вернемся к нашей аналогии с баскетболом: как только просвистел арбитр, что происходит дальше? Игроки останавливаются, и игра временно прекращается. Обычный ход игры нарушен.

В языке C++ мы используем ключевое слово try для определения блока стейтментов (так называемого «блока try»). Блок try действует как наблюдатель в поисках исключений, которые были выброшены каким-либо из операторов в этом же блоке try, например:

// Здесь мы пишем стейтменты, которые будут генерировать следующее исключение
throw — 1 ; // типичный стейтмент throw

Обратите внимание, блок try не определяет, КАК мы будем обрабатывать исключение. Он просто сообщает компилятору: «Эй, если какой-либо из стейтментов внутри этого блока try сгенерирует исключение — поймай его!».

Обработка исключений

Пока арбитр не объявит о штрафном броске, и пока этот штрафной бросок не будет выполнен, игра не возобновится. Другими словами, штрафной бросок должен быть обработан до возобновления игры.

Фактически, обработка исключений — это работа блока(ов) catch. Ключевое слово catch используется для определения блока кода (так называемого «блока catch»), который обрабатывает исключения определенного типа данных.

Вот пример блока catch, который обрабатывает (ловит) исключения типа int:

catch ( int a )
// Обрабатываем исключение типа int
std :: cerr << "We caught an int exception with value" << a << '\n' ;

Блоки try и catch работают вместе. Блок try обнаруживает любые исключения, которые были выброшены в нем, и направляет их в соответствующий блок catch для обработки. Блок try должен иметь, по крайней мере, один блок catch, который находится сразу же за ним, но также может иметь и несколько блоков catch, размещенных последовательно (друг за другом).

Как только исключение было поймано блоком try и направлено в блок catch для обработки, оно считается обработанным (после выполнения кода блока catch), и выполнение программы возобновляется.

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

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

catch ( double ) // примечание: Мы не указываем имя переменной, так как в этом нет надобности (мы её нигде в блоке не используем)

// Обрабатываем исключение типа double здесь
std :: cerr << "We caught an exception of type double" << '\n' ;

Это предотвратит вывод предупреждений компилятора о неиспользуемых переменных.

Использование throw, try и catch вместе

Вот полная программа, которая использует throw, try и несколько блоков catch:

// Здесь мы пишем стейтменты, которые будут генерировать следующее исключение
throw — 1 ; // типичный стейтмент throw
catch ( int a )
// Любые исключения типа int, сгенерированные в блоке try, приведенном выше, обрабатываются здесь
std :: cerr << "We caught an int exception with value: " << a << '\n' ;

catch ( double ) // мы не указываем имя переменной, так как в этом нет надобности (мы её нигде в блоке не используем)

// Любые исключения типа double, сгенерированные в блоке try, приведенном выше, обрабатываются здесь
std :: cerr << "We caught an exception of type double" << '\n' ; catch ( const std :: string &str ) // ловим исключения по константной ссылке

// Любые исключения типа std::string, сгенерированные внутри блока try, приведенном выше, обрабатываются здесь

std :: cerr << "We caught an exception of type std::string" << '\n' ; std :: cout << "Continuing our way!\n" ;

Результат выполнения программы:

We caught an int exception with value -1
Continuing our way!

Оператор throw используется для генерации исключения -1 типа int. Затем блок try обнаруживает оператор throw и перемещает его в соответствующий блок catch, который обрабатывает исключения типа int. Блок catch типа int и выводит соответствующее сообщение об ошибке.

После обработки исключения, программа продолжает свое выполнение и выводит на экран Continuing our way! .

Резюмируем

Обработка исключений, на самом деле, довольно-таки проста, и всё, что вам нужно запомнить, размещено в следующих двух абзацах:

При выбрасывании исключения (оператор throw), точка выполнения программы немедленно переходит к ближайшему блоку try. Если какой-либо из обработчиков catch, прикрепленных к блоку try, обрабатывает этот тип исключения, то точка выполнения переходит в этот обработчик и, после выполнения кода блока catch, исключение считается обработанным.

Если подходящих обработчиков catch не существует, то выполнение программы переходит к следующему блоку try. Если до конца программы не найдены соответствующие обработчики catch, то программа завершает свое выполнение с ошибкой исключения.

Обратите внимание, компилятор не выполняет неявные преобразования при сопоставлении исключений с блоками catch! Например, исключение типа char не будет обрабатываться блоком catch типа int, а исключение типа int, в свою очередь, не будет обрабатываться блоком catch типа float.

Это действительно всё, что вам нужно запомнить.

Исключения обрабатываются немедленно

Вот маленькая программа, которая демонстрирует, что исключения обрабатываются немедленно:

Как работают с исключениями и блоком try catch

Вот есть блок try catch, в нём можно обрабатывать исключения. А как им корректно пользоваться?
Если мы обрабатываем какие-то данные в try , то при каком-то некорректном поведении мы попадаем в блок catch(. ) . Тут всё, кажется, просто и понятно. Но как же этим пользоваться в больших проектах, где все дальнейшие строки кода зависят от результата обработки в этом try catch?
Вот небольшой тривиальный пример, который мне пришёл в голову. Корректна ли в общем такая архитектура?

bool DIV(int a, int b) < if (b == 0) throw 1; int c = a / b; std::cout int main() < bool Continue = true; int a, b; while (Continue) < try < std::cin >> a; std::cin >> b; Continue = DIV(a, b); > catch (. ) < std::cout std::cout return 0; > 

Отслеживать
411 6 6 серебряных знаков 22 22 бронзовых знака
задан 26 дек 2018 в 9:13
712 2 2 золотых знака 7 7 серебряных знаков 21 21 бронзовый знак

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

26 дек 2018 в 9:39

@ARHovsepyan что Вы имеете в виду под указанием в объявлении ф-и списка исключений? Вы про void funct() throw(AnyError) <. >?

26 дек 2018 в 9:42

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

26 дек 2018 в 9:43

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

26 дек 2018 в 9:47

@AR Hovsepyan, синтаксис throw(type1, type2, . ) признан устаревшим в C++11 и полностью удален из языка в C++17. Не советуйте писать некорректный код

27 дек 2018 в 10:57

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Исключения позволяют отложить обработку возникшей ошибки (исключительной ситуации) до момента, когда будет ясно как эту ошибку обработать. При этом по умолчанию (т.е. без какого-либо обработчика) ошибка не может быть просто проигнорирована, как это можно было бы делать со всевозможными кодами возвратов из функций или вариациями глобальной переменной errno . Если исключение вывалится на глобальный уровень, произойдёт аварийное завершение программы (вызовется std::terminate ).

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

Отслеживать
ответ дан 26 дек 2018 в 10:34
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков

Ответ конечно полезный, но не понел какая часть отвечает на вопрос: «как пользоваться этим в больших проектах»? Мне показалось имеется ввиду как узнать когда какое исключение нужно пытаться ловить?

26 дек 2018 в 12:22

@ARHovsepyan ловить нужно те исключения, которые пользователю кода (библиотеки) понятно как обработать. Конкретный перечень типов исключений, которые может породить тот или иной библиотечный код, должен быть опубликован автором библиотеки.

26 дек 2018 в 12:51

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

Урок #12 – Обработчик исключений. Оператор try-catch

Урок #12 – Обработчик исключений. Оператор try-catch

Порой при выполнении программ возникают ошибки. Некоторые из них могут приводить к фатальному завершению программы. Чтобы такого не произошло стоит использовать обработчик исключений. За урок мы научимся использовать конструкцию try-catch.

Видеоурок

Что такое исключение?

Предположим, что вы разработали программу «Текстовый редактор». В программе пользователь может создать новый файл, вписать в него данные и далее сохранить файл в системе.

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

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

Получается, исключение — это ошибка, что возникает в ходе работы самой программы. Отслеживать такие ошибки при помощи условных операторов не всегда возможно, ведь программа уже запущена, поведение пользователя нам неизвестно заранее, а значит и «ловить» ошибку нам нужно в момент её создания.

Отлов ошибок

Для вышеописанного случая как раз и нужна конструкция try catch для отлова ошибок в момент их создания.

При помощи данной конструкции вы можете отслеживать ошибки различных форматов и событий. Можно отследить неверное открытие файла, можно отследить неверное подключение класса, можно отследить неверное написание переменной или функции, да чего уж там, можно отследить даже деление чисел на ноль!

Реализации конструкции try catch

Для добавления отслеживания ошибок можно прописать следующий код:

FileStream fs = null; try < // Открываем какой-либо файл fs = new FileStream(@"C: empdata.txt", FileMode.Open); StreamReader sr = new StreamReader(fs); string line; // Данные считываются из файла и выводятся в консоль line = sr.ReadLine(); Console.WriteLine(line); >catch(FileNotFoundException e) < // Если что-то пошло не так Console.WriteLine("Файл не найден!"); // Ниже сообщаем компилятору об конкретной ошибке, но программу не прекращаем throw new FileNotFoundException(@"[data.txt не в c: emp папке]", e); >finally < // Выполниться в любом случае if (fs != null) // Если файл открыт fs.Close(); // То закрываем его >

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

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

Если необходимо отследить несколько классов с ошибками, то можно добавить несколько блоков catch. Все они добавляются друг под другом точно также как в условных операторах.

Конструкция finally

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

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

Весь код будет доступен после подписки на проект!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *