【问题标题】:Why the fscanf is used 2 times with: while( !feof(File))为什么 fscanf 使用 2 次:while(!feof(File))
【发布时间】:2012-06-20 12:49:06
【问题描述】:

为什么在使用fscanf从文件中获取数据时,使用了2次,一次在"!feof(fin)"之前和之后,如下代码所示:

fscanf(fin, "%s", letta);
while(!feof(fin)){

    fscanf(fin, "%s", letta);
}

读的字不一样?

【问题讨论】:

标签: c scanf feof


【解决方案1】:

不,read这个词是不一样的,因为你从文件中读取了两次,每次都会得到不同的数据。

while 中的条件测试您是否在文件末尾,为此必须进行读取尝试,这需要fscanf() before循环。

一旦进入循环,您就想继续从文件中读取。大概循环内会有更多的代码来处理你正在读取的数据。

在您发布的代码中,如果您在第一次尝试读取时遇到文件结尾,您将不会进入 (while) 循环。

将此与do-while 构造进行对比,其中测试位于循环的底部(即读取仅发生一次,位于循环的“底部”)。在那里你总是会至少进入循环一次。

【讨论】:

    【解决方案2】:

    在这里像这样使用feof() 可能没有意义,但许多正在学习 C 的人(我想,如果我弄错了,请道歉)似乎“想要”。

    事实上fscanf()本身有一个返回值;如果文件结束,它将无法执行请求的扫描,它会告诉您。如果文件结束,它甚至会返回特殊常量EOF。所以只需循环fscanf()的返回值:

    while( fscanf(fin, "%s", letta) == 1 )
    {
       /* Process, parse, store or do whatever with letta. */
    }
    

    【讨论】:

    • 没错,没错,但这并不能直接回答问题。
    【解决方案3】:

    因为只有在调用 fscanf 后才会设置 EOF 标志。当fscanf 尚未被调用时,条件while(!feof(fin)) 没有意义。

    【讨论】:

      【解决方案4】:

      feof 直到您尝试读取文件末尾之后才返回 true。想象一个像下面这样的文件:

      这是一个测试$ ^

      其中^ 表示文件中的当前位置,$ 表示 EOF。第一次调用fscanf(fin, "%s", letta); 后,流如下所示:

      这是一个测试$ ^

      循环的三次迭代(读取“is”、“a”和“test”)后,您将得到:

      这是一个测试$ ^

      此时,feof(fin) 仍然返回 false,因为此时您只知道您已经到达字符串“test”的末尾。因此,您的循环将再执行一次。因为你在文件的末尾,没有什么要读的,所以letta的内容不会改变,所以看起来你已经读了两次“test”。 现在feof(fin) 将返回 true。

      这个故事的寓意是你不应该使用feof 作为你的循环条件;相反,您应该使用读取操作本身的结果,如下所示:

      errno = 0;
      while (fscanf(fin, "%s", letta) == 1)
      {
        // process letta
      }
      if (feof(fin))
      {
        printf("Reached end of file\n");
      }
      else
      {
        perror("Error on read");
      } 
      

      【讨论】:

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