首页 > 解决方案 > 在 C 语言中,验证参数和处理错误的一些最常见的选项是什么?

问题描述

假设我有以下代码:

int calcTotalLinesFromFile(FILE *source_file) {
    /* Calculate number of lines in source_file and return */
}

int addToFile(char *name_of_file, char *file_content, int line_num) {
    FILE *temporary_file;
    FILE *source_file;
    int temp = 1;
    int ch;

    if (access(file_name, F_OK) != 0) {
        fprintf(stderr, "Cannot add content to file %s: File does not exist.\n", name_of_file);
        return errno;
    }

    source_file = fopen(name_of_file, "r");
    if (source_file == NULL) {
        perror("Cannot add content to file");
        return errno;
    }

    int total_lines = calcTotalLinesFromFile(source_file);
    if (line_num > total_lines) {
        fprintf(stderr, "Entered line number exceeds maximum file line.\n");
        return -1;
    } else if (line_num < 1) {
        fprintf(stderr, "Entered line number must be greater than zero.\n");
        return -1;
    }

    temporary_file = fopen("tempfile.tmp", "w");
    if (temporary_file == NULL) {
        perror("Could not write content to file");
        return errno;
    }
    
    /* Add content to file */
    /*       ...           */

    fclose(source_file);
    fclose(temporary_file);

    int successful_delete = remove(source_file_name);
    if (successful_delete != 0) {
        perror("Could not delete source file");
        remove("tempfile.tmp");  /* Clean up after failure */
        return errno;
    }

    int successful_rename = rename("tempfile.tmp", source_file_name);
    if (successful_rename != 0) {
        perror("Could not rename new file");
        remove("tempfile.tmp") /* Clean up after failure */
        return errno
    }

    return 0;
}

在这里,我对几乎所有可能失败的函数执行错误检查,以便我可以让用户了解究竟出了什么问题,并防止他们输入会在程序中引发更多错误的数据。我唯一的问题是它使我的方法比平时长得多,而且如果不向下滚动,该方法肯定不能放在我的显示器上。我的问题如下:

  1. 在 C 中是否有其他错误处理选项?
  2. 我是否可能过于频繁地检查错误?
  3. 让调用者在将参数传递给方法之前验证参数是否也很常见?

编辑:修复语法错误。

标签: c

解决方案


First, it is not common practice to return errno. Typically functions return -1 and ask the caller to check errno. You especially shouldn't mix the two practices (you return -1 when fprintf fails but you return errno everywhere else). As for other options, one common idiom is using goto for cleanup. (See Valid use of goto for error management in C?)

You can never check errors too often. Nearly every call to the OS can fail somehow, so you should always check. Even fclose can fail.


推荐阅读