【问题标题】:feof() on Linux return true at one line later than the ending line [duplicate]Linux 上的 feof() 在结束行之后的一行返回 true [重复]
【发布时间】:2013-09-21 06:44:33
【问题描述】:

我是 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;
}

【问题讨论】:

  • 使用fgets(...) 作为你的循环条件。当读取更多字符失败时,它将返回NULL
  • feof 检查(或至少要注意的事情)的问题在于它记录在案:“此指标通常由尝试读取的流上的先前操作设置在文件结尾处或之后。”因此,您可能在文件末尾是正确的,并且在您进行另一次读取之前它仍然不会指示 EOF。因此,您完成的最后一个fgets 可能已超出文件末尾。正如@MohammadAliBaydoun 所指出的,您应该使用您的fgets 调用作为您的读取和您的EOF 检查循环。
  • 非常感谢。它有效。

标签: c linux fopen feof


【解决方案1】:

这是一个常见的反模式:

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

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

正确的模式是:

while (fgets(string, 400, file_para))
{

【讨论】:

    【解决方案2】:

    这是使用feof() 的错误方式。使用feof() 检测主要 I/O 功能之一失败后出现的问题。它不能预测您是否即将达到 EOF;它会告诉您某些 I/O 函数何时已报告 EOF。 C 不是帕斯卡;在 Pascal 中,您可以(必须?)在调用 I/O 函数之前检查 EOF。

    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.
    

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

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

    请注意,您可能会失败,因为即使 feof(file_para) 不计算,ferror(file_para) 的计算结果也会为真......所以也许您需要 while (!feof(file_para) &amp;&amp; !ferror(file_para)),但这确实只是更多的证据表明 while 循环应该是有条件的关于 I/O 功能,而不是 feof()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多