文件打开时的错误处理

时间:2014-01-21 19:52:24

标签: c file error-handling fopen fclose

[问题1]

当我将文件打开到函数中时,通常我会这样做:

int read_file (char *filename)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
        return 1;

    /* ... */

    return fclose(fin);
}

int main ()
{
    char filename[100];

    if ( read_file(filename) )
    {
        perror(filename);
        exit(1);
    }

    return 0;
}

通常0返回值是错误的(对吗?)然后我可以将之前的代码更改为:

int read_file (char *filename)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
        return 0;

    /* ... */

    return !fclose(fin);
}

int main ()
{
    char filename[100];

    if ( !read_file(filename) )
    {
        perror(filename);
        exit(1);
    }

    return 0;
}

但我认为第一个代码更干净。

Another option只会将return 1;更改为return -1;(在我编写的第一个代码中)。

什么是最好的版本?

[问题2]

如果我必须处理更多错误,那么这样的代码是否正确?

int read_file (char *filename, int **vet)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
    {
        perror(filename);
        return 1;
    }

    * vet = malloc (10 * sizeof(int));
    if ( *vet == NULL )
    {
        perror("Memory allocation error.\n");
        return 1;   
    }

    /* ... */

    return fclose(fin);
}

int main ()
{
    char filename[100];
    int *vet;

    if ( read_file(filename, &vet) )
        exit(1);

    return 0;
}

1 个答案:

答案 0 :(得分:3)

Re Q1:

a)大多数POSIX函数实际上返回-1(或< 0)表示错误,而不是0.查看(例如)open()close()read(),{{ 1}}等等。例外是返回指针的POSIX调用,例如: write(),返回fopen()。这些错误会返回FILE *

b)我将我的代码编码为像POSIX函数一样工作,这类似于许多linux程序的内部。我称之为'UNIX C标准'。但是,许多C ++程序和Java程序使用NULL表示成功,true表示失败。当这些程序员转移到C时,他们使用1表示成功,0表示失败。这没有错,但确实会造成混乱(好吧,让我感到困惑)。最糟糕的结果是两个标准都在同一个程序中使用。选择一个标准并坚持它比你选择的标准更重要。

c)我自己的选择(与Q1相关)是错误时返回false(即根据你的“另一个选择”行)。

Re Q2:大多数是对的,是的。

a)如果您的计划成功,我认为最好-1而不是exit(0)

b)你return 0取决于你的位置。也许您想在perror中打印错误。

c)如果您在{{1}内无需清理或清理,则使用main()后紧跟perror(或者可能是不同的退出代码,具体取决于错误)是正常的。 }。

d)如果您在错误时返回exit(1)的结果,那么atexit失败时的返回应该是fclose()(或fopen)而不是1,就好像{ {1}}失败后返回-1(也称为EOF)。

e)Nit:您的fclose()函数应该包含参数(例如EOF