众所周知,在C语言中编写“完美的”错误处理代码非常困难(在其他语言中则非常困难)。
开发人员几乎总是忘记或丢弃的是在清理资源时处理错误。例如,忽略fclose返回值很危险。
无论如何,我试图在将in.txt复制到out.txt的小型C89程序中编写完美的错误处理代码。我的目标是编写易于检查和维护的代码。添加新的“资源”或在中间可能会失败的中间添加新的函数调用应该很容易。必须尽可能避免代码重复。我的基本设计很简单:所有资源都必须初始化为“空”。如果发生错误,我只是跳转到“handle_error”。最后,我总是称呼“free_resources”。可以多次执行“handle_error”和“free_resources”部分(例如,如果在释放资源时发生错误),而不会出现问题。
我的代码“完美”吗?
#include <stdio.h>
typedef int status;
#define SUCCESS 1
#define FAILURE 0
#define INPUT_FILE "in.txt"
#define OUTPUT_FILE "out.txt"
#define BUFFER_SIZE 2097152
char buffer[BUFFER_SIZE];
status copy_file()
{
FILE *input_file = NULL;
FILE *output_file = NULL;
size_t read_bytes;
size_t written_bytes;
status result;
input_file = fopen(INPUT_FILE, "rb");
if (!input_file) {
perror("Failed to open input file");
goto handle_error;
}
output_file = fopen(OUTPUT_FILE, "wb");
if (!output_file) {
perror("Failed to open output file");
goto handle_error;
}
while (1) {
read_bytes = fread(buffer, 1, sizeof(buffer), input_file);
if (read_bytes != sizeof(buffer) && ferror(input_file)) {
fprintf(stderr, "Failed to read from input file.\n");
goto handle_error;
}
written_bytes = fwrite(buffer, 1, read_bytes, output_file);
if (written_bytes != read_bytes) {
fprintf(stderr, "Failed to write to output file.\n");
goto handle_error;
}
if (read_bytes != sizeof(buffer))
break;
}
result = SUCCESS;
free_resources:
if (output_file) {
if (fclose(output_file)) {
output_file = NULL;
perror("Failed to close output file");
goto handle_error;
}
output_file = NULL;
}
if (input_file) {
if (fclose(input_file)) {
input_file = NULL;
perror("Failed to close input file");
goto handle_error;
}
input_file = NULL;
}
return result;
handle_error:
result = FAILURE;
goto free_resources;
}
int main()
{
return copy_file() ? 0 : 1;
}
最佳答案
C语言不提供对错误处理的任何直接支持。但是,在error.h头文件中定义的一些方法和变量可用于通过函数中的return语句指出错误。在C语言中,如果出现任何错误,函数将返回-1或NULL值,并使用错误代码设置全局变量errno。因此,返回值可用于在编程时检查错误。
每当使用C语言进行函数调用时,就会将一个名为errno的变量与之关联。它是一个全局变量,可用于根据函数的值来确定函数执行时遇到的错误类型。
C语言使用以下函数来表示与errno相关的错误消息:
指向当前errno值的字符串表示形式的指针。
关于c - 如何在C语言中编写完美的错误处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62271524/