【问题标题】:How to use feof(FILE *f)?如何使用 feof(FILE *f)?
【发布时间】:2011-05-17 00:06:57
【问题描述】:

我很难使用 do-while 循环,它应该停止 当我们到达文件末尾时。这是循环代码:

do  {
    if (pcompanyRow[0] != '#' && pass == 1) {
        strtok(pcompanyRow, ":");
        pcompanyName = strcpy(pcompanyName, strtok(NULL, ""));
        pass = 2;
        fgets(pcompanyRow, 1024, f);
    }
    if (pcompanyRow[0] != '#' && pass == 2) {
        strtok(pcompanyRow, ":");
        pcompanySMSPrice = strcpy(pcompanySMSPrice, strtok(NULL , ""));
        pass = 3;
        fgets(pcompanyRow, 1024 , f);
    }
    if (pcompanyRow[0] != '#' && pass == 3) {
        strtok(pcompanyRow, ":");
        pcompanyMMSPrice = strcpy(pcompanyMMSPrice, strtok(NULL, ""));
        pass = 4;
        fgets(pcompanyRow, 1024, f);
    }
    if (pass == 4)  {
        AppendCompanyNode(pcompanyList, pcompanyName, pcompanySMSPrice, pcompanyMMSPrice);
        pass = 1;
    }
} while (!feof(f));

使用调试器运行后,我注意到我遇到的所有崩溃问题都是因为它即使到达整行也没有退出这个循环。

我应该如何正确写?

【问题讨论】:

  • 正如答案所说,简洁的答案是“你不使用 feof()”。您使用 'feof()' 的唯一时间是当您从主要输入函数(例如fgets())获得错误或 eof 指示并且您决定要区分 EOF 和错误时。大多数情况下,大多数人都懒得区分两者(特别是我,但我见过的大部分代码)。我根本不记得使用过feof() - 这意味着我可能在过去四分之一世纪的 C 编程中使用过几次。
  • @Jonathan:如果您想知道是否发生错误,我认为检查ferror(f) 而不是!feof(f) 更有意义。有时feof 在 do-while 循环中很有用,但我同意它在大多数情况下都没什么用。
  • @R..:是的,使用ferror() 比使用feof() 更有意义,但我承认我也不经常使用它。但我应该在我的评论中这么说 - 或者添加第二个,因为我的空间用完了。

标签: c loops while-loop eof feof


【解决方案1】:

你不应该使用 feof() 作为循环的退出指示符。 feof() 仅在读取文件末尾 (EOF) 后为 TRUE,而不是在到达 EOF 时为 TRUE

来源here。它还详细解释了问题以及如何解决它。

【讨论】:

  • 我将 while 更改为:while(fgets(pcompanyRow, 1024 , f) != NULL)
  • 无论如何它不会停止!我可以看到 pcompanyRow 的值,它再次占用了第一行,它给我带来了循环中的文件行并且不会停止......我该怎么办?
  • +1,但我质疑措辞。 EOF 永远不会“读取”。读取函数可能会因遇到文件结尾而返回 EOF,但 EOF 不是读取的值。
  • 您指出的代码显示由于 feof() 而执行了额外的读取。我运行了完全相同的代码,我没有遇到这个问题。任何想法为什么?
【解决方案2】:

我会改变你的循环和逻辑来使用它:

while (fgets(pcompanyRow, 1024, f) != NULL) {

    /* do things */

}

当 fgets() 尝试读取文件末尾之后,它将返回 NULL 并且您将跳出循环。您仍然可以继续使用pass 和您的其他标志/逻辑,但您检查的条件会略有不同。

【讨论】:

  • 循环完成后,您可以使用 feof(f) 来确定它是 EOF 还是错误
  • 这就是我所做的......但它仍然不会停止!继续给我带来台词
【解决方案3】:

我建议同时使用 fgets() 和 feof()。 文件中的最后一个字符串可能有 \n 也可能没有。如果只使用 feof(),则可以跳过(丢失)最后一行。

 for(;;)
 {char *pc;

  pc=fgets(buf,sizeof(buf),fd);

  if(!pc)
    {//it may be read error or end of file
      if(feof(fd))
        {//it is end of file, normal exit from for
         break;      
        }
       else
        {//it is i/o error 
         fclose(fd);
         return 2;
        }
    }
}//for

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多