Linux 上的 feof() 在比结束行 [duplicate] 晚一行返回 true

feof() on Linux return true at one line later than the ending line [duplicate]

提问人:Dan 提问时间:9/17/2013 最后编辑:lurkerDan 更新时间:9/17/2013 访问量:2351

问:

我是 C 语言的初学者。当我使用这个 while 循环打印文件的包含时。最后一行将在 Linux 上打印两次。当到达文件末尾时,它不应该进入 while 循环。它在 Windows 上没有问题。

#include <stdio.h>
#include <unistd.h>

int main()
{

    char string[400];
    FILE *file_para;

    // Open the file
    if ((file_para = fopen("Test.txt", "r")) == NULL)
    {
        printf("cannot open file\n");
        getchar();
        return 0;
    }

    while (!feof(file_para))
    {
        fgets(string, 400, file_para);
        printf("**** %s", string);
    }

    fclose(file_para);
    getchar();
    return 0;
}
C Linux fopen feof

评论

1赞 user123 9/17/2013
用作循环条件。当它无法读取更多字符时,它将返回。fgets(...)NULL
2赞 lurker 9/17/2013
检查的问题(或者至少是要注意的事情)是它被记录在案:“这个指示器通常是由流上的一个操作设置的,该操作试图在文件末尾或超过文件末尾读取。因此,您可能正好位于文件末尾,并且在您进行另一次读取之前,它仍然不会指示 EOF。因此,您完成的最后一个可能是文件末尾。如@MohammadAliBaydoun所示,您应该使用您的调用作为您的读取和 EOF 检查循环。feoffgetsfgets

答:

1赞 caf 9/17/2013 #1

这是一种常见的反模式:

while (!feof(file_para))
{
    fgets(string, 400, file_para);

feof()不检测下一个输入调用是否因文件结束而失败;它会告诉您文件是否到达文件末尾。您应该只在输入函数失败调用它,以查看它失败的原因(可能是错误或文件结束)。

正确的模式是:

while (fgets(string, 400, file_para))
{
1赞 Jonathan Leffler 9/17/2013 #2

这是错误的使用方式。用于检测其中一个主要 I/O 功能发生故障后出现的问题。它不能预测您是否即将达到 EOF;当某些 I/O 函数已经报告 EOF 时,它会告诉您。C 不是 Pascal;在 Pascal 中,您可以在调用 I/O 函数之前(必须)检查 EOF。feof()feof()

while (fgets(string, sizeof(string), file_para) != 0)
{
    ...do printing, etc...
}
// If you need to, use `feof()` and `ferror()` to sort out what went wrong.

如果你真的坚持使用 ,那么你还需要检查你的 I/O 操作:feof()

while (!feof(file_para))
{
    if (fgets(string, sizeof(string), file_para) == 0)
        break;
    ...do printing, etc...
}

请注意,您可能会失败,因为即使不计算结果为 true,也可能失败......所以也许你需要 ,但这实际上只是更多的证据,表明循环应该以 I/O 函数为条件,而不是 .ferror(file_para)feof(file_para)while (!feof(file_para) && !ferror(file_para))whilefeof()