Обработка ошибок в C: лучшие практики и техники
Язык C не имеет встроенного механизма исключений, но как системный язык он даёт доступ к кодам ошибок через возвращаемые значения. Большинство функций C и Unix при ошибке возвращают -1 или NULL и устанавливают глобальную переменную errno (объявлена в <errno.h>).
Хорошая практика: в начале программы устанавливать errno = 0; значение 0 означает отсутствие ошибки.
errno, perror() и strerror()
Для вывода текстового описания ошибки используют две функции:
- perror(const char *s) — печатает в
stderrстрокуs, затем «: », затем текстовое описание текущегоerrno. - strerror(int errnum) — возвращает указатель на строку с описанием ошибки
errnum.
Все сообщения об ошибках следует выводить в поток stderr.
Пример: попытка открыть несуществующий файл
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *pf;
int errnum;
pf = fopen("unexist.txt", "rb");
if (pf == NULL) {
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("Error printed by perror");
fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
} else {
fclose(pf);
}
return 0;
}
Результат (код ошибки 2 — ENOENT):
Value of errno: 2
Error printed by perror: No such file or directory
Error opening file: No such file or directory
Ошибки деления на ноль
Частая проблема — деление без проверки делителя на ноль. Это приводит к ошибке времени выполнения (SIGFPE).
Правильный подход: проверка перед делением
#include <stdio.h>
#include <stdlib.h>
int main() {
int dividend = 20;
int divisor = 0;
int quotient;
if (divisor == 0) {
fprintf(stderr, "Division by zero! Exiting...\n");
exit(EXIT_FAILURE);
}
quotient = dividend / divisor;
fprintf(stderr, "Value of quotient : %d\n", quotient);
exit(EXIT_SUCCESS);
}
Результат при divisor = 0:
Division by zero! Exiting...
Статус выхода программы
Стандартные макросы из <stdlib.h>:
- EXIT_SUCCESS (обычно
0) — успешное завершение; - EXIT_FAILURE (обычно
1) — завершение с ошибкой.
Использование этих макросов делает код переносимым и понятным.
Пример с EXIT_SUCCESS / EXIT_FAILURE
#include <stdio.h>
#include <stdlib.h>
int main() {
int dividend = 20;
int divisor = 5;
int quotient;
if (divisor == 0) {
fprintf(stderr, "Division by zero! Exiting...\n");
exit(EXIT_FAILURE);
}
quotient = dividend / divisor;
fprintf(stderr, "Value of quotient : %d\n", quotient);
exit(EXIT_SUCCESS);
}
Результат:
Value of quotient : 4
Язык C
- Работа с файлами в C: мастерство ввода-вывода с fopen, fprintf, fread и fseek
- Обработка исключений в Java: try, catch, finally, throw и throws
- Мастерство частоты ошибок кода ADC: Что нужно знать
- Лучшие практики хранения и транспортировки приводных ремней
- Работа с файлами в C# — практическое руководство
- Освоение обработки сигналов в C++: безопасное управление прерываниями и корректное завершение программы
- Обработка исключений в C#: try, catch, finally, throw и лучшие практики
- Обработка исключений в Python: подробное руководство
- Мастерство безопасности при movimentации материалов: лучшие практики для эффективных безрисковых операций
- Понимание манипулирования материалами: ключевые концепции и лучшие практики