fgets()的返回值是什么?

16

我最近才开始使用 C 中的 I/O。这是我的问题 -
我有一个文件,从中读取输入。然后我使用 fgets() 将字符串读入缓冲区,以某种方式利用。现在,如果输入对于缓冲区来说太短,即如果第一次 fgets() 读取到 EOF,会发生什么?fgets() 是否应该返回 NULL(正如我在 fgets() 文档中所读到的)?似乎它没有返回,我也能够正确获取输入。此外,即使我的 feof(input) 也没有表示我们已经到达了 EOF
以下是我的代码片段。

char    buf[BUFSIZ];
FILE    *input,
        *output;

input   = fopen(argv[--argc], "r");
output  = fopen(argv[--argc], "w");

/**
 *  If either of the input or output were unable to be opened
 *          we exit
 */
if (input == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 1]);
    exit(EXIT_FAILURE);
}

if (output == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 0]);
    exit(EXIT_FAILURE);
}

if (fgets(buf, sizeof(buf), input) != NULL) {
    ....
}

/**
 *  After the fgets() condition exits it is because, either -
 *      1) The EOF was reached.
 *      2) There is a read error.
 */
if (feof(input)) {
    fprintf(stdout, "Reached EOF.\n");
}
else if (ferror(input)) {
    fprintf(stdout, "Error while reading the file.\n");
}

5
请注意,feof(input)仅在尝试读取超过 EOF后才会返回真值。它并不告诉你是否处于 EOF。 - lurker
在上面的例子中,你能解释一下吗?假设fgets()只读取了100个字节BUFSIZE为512),那么fgets()应该返回NULL吗? - yadav_vi
好的,现在我意识到我的评论有多愚蠢了;不管怎样,我明白你的意思了。我该如何检查是否已达到EOF? - yadav_vi
1个回答

17

fgets()的文档并没有说明你认为的那样:

根据我的manpage

fgets()从流中读取不超过size-1个字符,将其存储到指向s缓冲区的指针中。读取会在遇到EOF或换行符后停止。如果读取到换行符,则将其存储到缓冲区中。终止空字节('\0')存储在缓冲区中的最后一个字符之后。

稍后又说到

gets()fgets()成功时返回s,出现错误或在未读取任何字符时发生文件结束时返回NULL

我并不认为这意味着EOF将被视为错误条件并返回NULL。事实上,它只表示EOF未读取任何字符时才会返回NULL

POSIX标准(参考不太容易阅读的C标准)在这里:http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html并且说明:

成功完成后,fgets()将返回s。如果流位于文件结尾,则为该流设置文件结束标志,并且fgets()将返回空指针。如果发生读取错误,则为该流设置错误标志,fgets()将返回空指针,并设置errno以指示错误。

这明确表示当调用它时,只有在实际到达 EOF 时才会返回 NULL,也就是说,如果读取了任何字节,它将不会返回 NULL


你能解释一下 feof() 部分吗,为什么它没有打印任何东西。EOF 已经到达了对吧? - yadav_vi
feof()函数测试文件结束标志,该标志仅在您已经尝试读取超出文件末尾的位置时设置。它不会(令人困惑地)指示您已到达文件末尾。 - abligh
2
如果您再次执行 fgets(),您将会得到 EOF。这是测试的正常方式。 - abligh
1
@yadav_vishal,就像abligh所说的那样。您可以继续使用fgets,直到看到它返回NULL以结束循环。此时,feof应该为TRUE,因为NULL表示fgets试图读取超过EOF。 - lurker
1
明白了!谢谢!我应该使用 while(),而不是 if() - yadav_vi
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接