在C语言中,验证参数和处理错误最常用的选项是什么?

在C语言中,验证参数和处理错误最常用的选项是什么?,c,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

假设我有以下代码:

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;
}
int-calcTotalLinesFromFile(文件*源文件){
/*计算源_文件中的行数并返回*/
}
int addToFile(char*文件名、char*文件内容、int行数){
文件*临时文件;
文件*源文件;
内部温度=1;
int-ch;
if(访问(文件名,F\u确定)!=0){
fprintf(stderr,“无法向文件%s添加内容:文件不存在。\n”,文件的名称);
返回errno;
}
source_file=fopen(_文件的名称,“r”);
if(source_file==NULL){
perror(“无法向文件添加内容”);
返回errno;
}
int TOTALL_lines=calcTotalLinesFromFile(源文件);
如果(行数>行总数){
fprintf(stderr,“输入的行号超过最大文件行。\n”);
返回-1;
}否则如果(行数<1){
fprintf(stderr,“输入的行号必须大于零。\n”);
返回-1;
}
临时文件=fopen(“tempfile.tmp”,“w”);
if(临时_文件==NULL){
perror(“无法将内容写入文件”);
返回errno;
}
/*向文件中添加内容*/
/*       ...           */
fclose(源文件);
fclose(临时文件);
int successful_delete=remove(源文件名);
如果(成功删除!=0){
perror(“无法删除源文件”);
删除(“tempfile.tmp”);/*故障后清理*/
返回errno;
}
int successful_rename=rename(“tempfile.tmp”,源文件名);
如果(成功_重命名!=0){
perror(“无法重命名新文件”);
删除(“tempfile.tmp”)/*故障后清理*/
返回错误号
}
返回0;
}
在这里,我对几乎所有可能失败的函数执行错误检查,这样我就可以让用户知道到底出了什么问题,并防止他们输入会在程序中引发更多错误的数据。我唯一的问题是,它使我的方法比正常方法长得多,而且如果不向下滚动,这种方法肯定无法安装在我的显示器上。我的问题如下:

  • 在C语言中还有其他错误处理选项吗
  • 我是否经常检查错误
  • 在将参数传递给方法之前让调用方验证参数是否也很常见

  • 编辑:修复语法错误。

    首先,返回errno不是常见的做法。通常,函数返回-1并要求调用方检查errno。您尤其不应该混合使用这两种做法(当
    fprintf
    失败时返回-1,但在其他地方返回
    errno
    )。至于其他选项,一个常见的习惯用法是使用
    goto
    进行清理。(见附件)


    你再也不能经常检查错误了。几乎每个对操作系统的调用都可能以某种方式失败,因此您应该经常检查。甚至
    fclose
    也可能失败。

    这可能与此相关:
    access
    可能由于文件不存在以外的原因而失败。如果该文件存在,并且您编写了一条错误消息,表明它不存在,那么您就混淆了用户。不要编造错误信息;使用系统通过
    errno
    提供的字符串。例如
    perror(文件名)
    “太频繁”取决于此代码的用例。只是你在闲逛?可能如果是为了用户和长期部署,可能还不够。列出特定的错误代码有助于诊断,例如
    “E2930无法写入文件”
    ,允许您快速识别故障线路。@williampersell但如果我通过
    F_OK
    标志,那么除了不存在的文件之外,还有什么其他原因会导致故障?@Phoenix ENOTDIR、enametoolog、ELOOP等。。。