Обработка ошибок
Введение в обработку ошибок при валидации входных данных
Обработка ошибок является важной частью валидации входных данных, которая обеспечивает надежное и безопасное выполнение программы. Корректное управление ошибками помогает предотвратить неожиданное поведение и предоставить осмысленную обратную связь пользователям.
Стратегии обработки ошибок
1. Подход с возвращаемым значением
enum ValidationResult {
VALID_INPUT = 0,
ERROR_EMPTY_INPUT = -1,
ERROR_INVALID_FORMAT = -2,
ERROR_OUT_OF_RANGE = -3
};
int validate_input(const char *input, int min, int max) {
if (input == NULL || strlen(input) == 0) {
return ERROR_EMPTY_INPUT;
}
char *endptr;
long value = strtol(input, &endptr, 10);
if (*endptr != '\0') {
return ERROR_INVALID_FORMAT;
}
if (value < min || value > max) {
return ERROR_OUT_OF_RANGE;
}
return VALID_INPUT;
}
2. Механизм логирования ошибок
#include <stdio.h>
#include <time.h>
void log_validation_error(const char *input, int error_code) {
FILE *log_file = fopen("validation_errors.log", "a");
if (log_file == NULL) {
perror("Error opening log file");
return;
}
time_t current_time;
time(¤t_time);
fprintf(log_file, "[%s] Input: %s, Error Code: %d\n",
ctime(¤t_time), input, error_code);
fclose(log_file);
}
Шаблоны обработки ошибок
Шаблон |
Описание |
Сценарий использования |
Возвращаемые коды |
Числовые индикаторы ошибок |
Простая передача информации об ошибке |
Логирование ошибок |
Постоянный отслеживание ошибок |
Отладка и мониторинг |
Обработка исключений |
Прерывание нормального потока выполнения |
Сложные сценарии ошибок |
Механизм обратного вызова |
Пользовательская обработка ошибок |
Гибкое управление ошибками |
Диаграмма потока обработки ошибок
graph TD
A[Input Received] --> B{Validate Input}
B -->|Valid| C[Process Input]
B -->|Invalid| D[Error Detection]
D --> E{Error Type}
E -->|Logging| F[Write to Log]
E -->|User Feedback| G[Display Error Message]
E -->|Critical| H[Terminate Program]
Продвинутые методы обработки ошибок
Пользовательский обработчик ошибок
typedef struct {
int error_code;
const char *error_message;
void (*error_handler)(const char *input);
} ErrorHandler;
void handle_input_error(const char *input) {
ErrorHandler handlers[] = {
{ERROR_EMPTY_INPUT, "Empty input not allowed", default_error_handler},
{ERROR_INVALID_FORMAT, "Invalid input format", format_error_handler},
{ERROR_OUT_OF_RANGE, "Input out of acceptable range", range_error_handler}
};
for (size_t i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) {
if (handlers[i].error_code == current_error) {
log_validation_error(input, handlers[i].error_code);
handlers[i].error_handler(input);
break;
}
}
}
Полный пример обработки ошибок
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_INPUT_LENGTH 50
int main() {
char input[MAX_INPUT_LENGTH];
int result;
while (1) {
printf("Enter a number (1-100, or 'q' to quit): ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = 0;
if (strcmp(input, "q") == 0) {
break;
}
result = validate_input(input, 1, 100);
switch (result) {
case VALID_INPUT:
printf("Valid input: %ld\n", strtol(input, NULL, 10));
break;
case ERROR_EMPTY_INPUT:
log_validation_error(input, result);
printf("Error: Empty input\n");
break;
case ERROR_INVALID_FORMAT:
log_validation_error(input, result);
printf("Error: Invalid number format\n");
break;
case ERROR_OUT_OF_RANGE:
log_validation_error(input, result);
printf("Error: Number out of range\n");
break;
}
}
return 0;
}
Лучшие практики
- Всегда валидируйте и обрабатывайте потенциальные ошибки
- Предоставляйте четкие сообщения об ошибках
- Логируйте ошибки для отладки
- Реализуйте плавное восстановление после ошибки
- Используйте осмысленные коды ошибок
LabEx рекомендует реализовывать комплексную обработку ошибок для создания надежных и удобных в использовании программ на языке C.