Foreversoft.ru

IT Справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Типы ошибок c

Обработка ошибок в программах на Си

Хотя C не обеспечивает прямой поддержки обработки ошибок (или обработки исключений), существуют способы, с помощью которых обработка ошибок может быть осуществлена в C. Программист должен в первую очередь предотвращать ошибки и тестировать возвращаемые значения из функций.
Многие вызовы функций C возвращают -1 или NULL в случае ошибки, поэтому быстрое тестирование этих возвращаемых значений легко выполнить, например, с помощью оператора if. Например, в Socket Programming возвращаемое значение функций, таких как socket (), listen () и т. Д., Проверяется на наличие ошибки или нет.

Пример: обработка ошибок в программировании сокетов

Различные методы обработки ошибок в C

    Глобальная переменная errno: когда в C вызывается функция, переменной с именем errno автоматически присваивается код (значение), который можно использовать для определения типа возникшей ошибки. Это глобальная переменная, указывающая, что ошибка произошла во время любого вызова функции и определена в заголовочном файле errno.h.
    Разные коды (значения) для errno означают разные типы ошибок. Ниже приведен список из нескольких различных значений errno и соответствующего значения:

// Реализация C, чтобы увидеть, как значение errno
// установить в случае любой ошибки в C
#include
#include

// Если файл открыт, который не существует,

// тогда это будет ошибка и соответствующая

// значение errno будет установлено

// открываем файл который

fp = fopen ( «GeeksForGeeks.txt» , «r» );

printf ( » Value of errno: %dn » , errno );

Примечание. Здесь значение errno установлено в 2, что означает — Нет такого файла или каталога. В онлайн-среде IDE может выдаваться ошибка № 13, в которой говорится, что разрешение отклонено.

  • perror () и strerror (): приведенное выше значение errno указывает типы возникших ошибок.
    Если требуется показать описание ошибки, то есть две функции, которые можно использовать для отображения текстового сообщения, связанного с errorno. Функции:
    • perror: отображает строку, которую вы передаете ей, затем двоеточие, пробел, а затем текстовое представление текущего значения errno.
      Синтаксис:
    • strerror (): возвращает указатель на текстовое представление текущего значения errno.
      Синтаксис:

    // Реализация C, чтобы увидеть, как perror () и strerror ()
    // функции используются для печати сообщений об ошибках.
    #include
    #include
    #include

    // Если файл открыт, который не существует,

    // тогда это будет ошибка и соответствующая

    // значение errno будет установлено

    fp = fopen ( » GeeksForGeeks.txt » , «r» );

    // открываем файл который

    printf ( «Value of errno: %dn » , errno );

    printf ( «The error message is : %sn» ,

    perror ( «Message from perror» );

    Выход:
    На личном рабочем столе:

    В онлайн IDE:

    Примечание . Функция perror () отображает переданную ей строку, за которой следует двоеточие и текстовое сообщение с текущим значением errno.

    Состояние выхода: Стандарт C определяет две константы: EXIT_SUCCESS и EXIT_FAILURE, которые могут быть переданы в exit () для указания успешного или неудачного завершения, соответственно. Это макросы, определенные в stdlib.h.

    // C реализация, которая показывает
    // использование EXIT_SUCCESS и EXIT_FAILURE.
    #include
    #include
    #include
    #include

    fp = fopen ( «filedoesnotexist.txt» , «rb» );

    printf ( «Value of errno: %dn» , errno );

    printf ( «Error opening the file: %sn» ,

    perror ( «Error printed by perror» );

    printf ( «I will not be printedn» );

    printf ( «I will not be printedn» );

    Ошибки деления на ноль: распространенная ошибка программистов на Си не проверяет, равен ли делитель нулю перед командой деления. Деление на ноль приводит к неопределенному поведению, нет никакой конструкции языка C, которая могла бы с этим что-либо делать. Лучше всего не делить на ноль в первую очередь, проверяя знаменатель.

    // C программа для проверки и исправления
    // делим на ноль
    #include
    #include

    void function( int );

    void function( int x)

    printf ( «Division by Zero is not allowed» );

    fprintf (stderr, «Division by zero! Exiting. n» );

    printf ( «f(x) is: %.5f» , fx);

    Эта статья предоставлена МАЖАР ИМАМ ХАН . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

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

    Обновл. 12 Янв 2020 |

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

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

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

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

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

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

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

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

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

    Читать еще:  Perform publication contract with message ошибка

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

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

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

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

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

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

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

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

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

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

    throw, try и catch вместе

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

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

    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.

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

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

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

    Типы ошибок c

    На 32-м уроке по C# мы начнем обзор обработки исключений. При возникновении непредвиденного события необработанные исключения приводят к аварийному завершению работы программы. Правильная обработка исключений позволяет выйти из ошибки без поломки программы или даже сеанса системы.

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

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

    Иерархия классов исключений

    При возникновении исключения нормальная обработка кода прекращается. Создается объект, содержащий информацию, относящуюся к ошибке. Этот объект является экземпляром класса исключений. Самым основным из классов исключений является Exception, определенный в пространстве имен System.

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

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

    • ArithmeticException. Выбрасывается при возникновении ошибки во время арифметической операции, приведения или преобразования.
    • DivideByZeroException. Возникает при попытке разделить значение на ноль. Является более специализированной версией исключения выше.
    • OverflowException. Выбрасывается, когда ошибка возникает во время арифметической операции или во время литья или преобразования, потому что результирующее значение слишком велико или мало. Исключение OverflowException является производным от исключения ArithmeticException.
    • OutOfMemoryException. Выбрасывается, когда доступной памяти недостаточно для продолжения выполнения.

    Приведенный выше список дает небольшую выборку классов исключений в иерархии. Гораздо более полный список можно найти на странице иерархии системных исключений веб-сайта Microsoft MSDN.

    Исключения приложений — это те, которые вы определяете. Они могут быть универсальными, например WordProcessorException, или специализированными, например LeftMarginTooSmallException. Конечно, ни одно из этих исключений не существует в .NET framework; они должны быть созданы перед использованием. Исключения приложений не будут обсуждаться до следующей статьи, в которой исследуются программные исключения.

    Читать еще:  Код ошибки 65536

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

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

    Основной блок Try / Catch

    C# предоставляет структуру кода, известную как блок try / catch, которая позволяет обрабатывать исключения. Основной блок try / catch имеет два элемента. Раздел try содержит одну или несколько выполняемых команд, удерживаемых в символах фигурной скобки < и >. Раздел catch содержит код для выполнения, если во время обработки раздела try происходит исключение. Основной синтаксис выглядит следующим образом:

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

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

    Извлечение информации об исключении

    Как написано выше, создание исключения включает в себя создание объекта исключения. Объект имеет свойства, содержащие информацию, описывающую ошибку. Это может быть прочитано кодом в блоке catch путем добавления объявления исключения к оператору catch. Следующий пример расширяет предыдущий код, объявляя объект наиболее обобщенного класса исключений. Все исключения будут пойманы, но теперь информация об исключении может быть использована при создании сообщения об ошибке.

    Приведенный выше пример улавливает любое исключение и заполняет объект класса Exception . Свойство объекта Message используется для вывода описания ошибки. Это одно из нескольких свойств, предоставляемых всеми классами исключений. Некоторые из самых полезных свойств являются:

    • Message. Строка, содержащая описание исключения.
    • Source. Строка, содержащая имя программы или объекта, вызвавшего исключение.
    • TargetSite. Объект, содержащий сведения о методе, вызвавшем исключение.
    • StackTrace. Строка, содержащая полный стек вызовов, которые привели к исключению. Эта строка позволяет программисту просматривать каждый вызов метода, выполненный до возникновения исключения. Это особенно полезно во время тестирования и отладки.
    • InnerException. Когда одно исключение возникает как прямой результат другого, начальное исключение может содержаться в этом свойстве. Внутреннее исключение содержит все стандартные свойства, включая, возможно,еще одно внутреннее исключение. Если нет внутреннего исключения, это свойство имеет значение null.

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

    Как ловить конкретные исключения

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

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

    Примечание: если достаточно поймать тип исключения и нет необходимости опрашивать свойства исключения, то нет необходимости включать имя переменной для объекта исключения. Catch в приведенном выше примере может быть сокращен до catch (DivideByZeroException) в такой ситуации.

    Перехват нескольких исключений

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

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

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

    Блок Try / Catch / Finally

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

    C# определяет блок добавления, который может быть добавлен в конец структуры try / catch. Это последний блок. Код в этом разделе гарантированно выполняется после блока try / catch, даже если возникает исключение или блок try содержит оператор return.

    Можно попробовать использовать Finally вместе с блоками catch. Если при использовании такой структуры возникает исключение, оно остается необработанным и передается вызывающей подпрограмме или системе времени выполнения C#. Однако код в блоке finally выполняется независимо от того, вызвано исключение или нет.

    Читать еще:  Обработчик ошибок в vba


    Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

    статьи IT, уроки по си шарп, си шарп, исключения, ошибки

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

    Обновл. 12 Янв 2020 |

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    throw, try и catch вместе

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

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

    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.

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

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

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

  • Ссылка на основную публикацию
    Adblock
    detector