文件打开时的错误处理

ᴜsᴇ*_*sᴇʀ 5 c error-handling fopen file 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;
}
Run Code Online (Sandbox Code Playgroud)

通常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;
}
Run Code Online (Sandbox Code Playgroud)

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

另一种选择是唯一的改变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;
}
Run Code Online (Sandbox Code Playgroud)

abl*_*igh 6

关于问题 1:

a) 大多数 POSIX 函数实际上会在错误时返回 -1(或 <0),而不是 0。(例如)open()close()、等等。例外是返回指针的 POSIX 调用,例如,它返回一个。这些错误返回。read()write()fopen()FILE *NULL

b) 我编写的代码像 POSIX 函数一样工作,这与许多 Linux 程序的内部结构类似。我将其称为“UNIX C 标准”。然而,许多 C++ 程序和 Java 程序都使用true成功和false失败。当这些程序员转向 C 时,他们用 1 表示成功,用 0 表示失败。这并没有错,但确实引起了混乱(好吧,让我感到困惑)。最糟糕的结果是在同一个程序中使用两种标准时。选择一个标准并坚持它比你选择哪个标准更重要。

c) 我自己的选择(相对于问题 1),将-1在错误时返回(即按照您的“另一个选择”行)。

回复 Q2:大部分是对的,是的。

exit(0)a) 如果你的计划成功了,那就比我想象的要好return 0

b) 完全由perror你决定。也许您想将错误打印在main().

c)如果您没有清理工作要做或perror在.exit(1)atexit

fclose()d) 如果您返回错误结果,则fopen失败时的返回值应该-1(或EOF)不是 1,就像fclose()失败时返回的那样EOF(也称为-1)。

e) Nit:你的main函数应该有参数(例如int main(char **argv, int argc)

  • **(Q2b)** _“`perror` 的位置取决于您。也许您想在 `main()` 中打印错误。”_ 但是如果我在 `main()` 中使用 `perror` 我无法区分错误!**(Q2d)** _“如果出错时返回 `fclose()` 的结果,那么 `fopen` 失败时的返回值应该是 `-1`(或 `EOF`),而不是像 `fclose` 那样的 1 ()` 失败,它返回 `EOF`(也称为 `-1`)。"_ 但如果 `fopen` 失败,它返回到 `main()`:直到 `fclose()` 才会到达。 (2认同)