c - 如何在C语言中编写完美的错误处理?

标签 c error-handling

众所周知,在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相关的错误消息:

  • perror():返回传递给它的字符串以及当前errno值的文本表示形式。
  • strerror()在string.h库中定义。此方法返回一个
    指向当前errno值的字符串表示形式的指针。
  • 关于c - 如何在C语言中编写完美的错误处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62271524/

    相关文章:

    C fputc 错误处理?

    c++ - 如果遇到错误,如何重复代码?

    c++ - CUDA如何欺骗内核认为它在另一个线程中?

    reactjs - 错误边界禁用交换机内部的路由

    objective-c - C 中的 OpenSSL Diffie Hellman DER 编码

    python - 使用 scipy.weave.inline 遍历数组数组

    angular - 错误发生后,Angular停止监听EventEmitter

    java - 为什么 Camel noErrorHandler 使用堆栈跟踪记录警告消息?

    c - 确定与等价函数的一对一对应关系的算法

    c - 释放其分配区域之外的内存