文件阅读中无法捕获的缺陷

时间:2014-03-06 15:09:03

标签: c

谁能告诉我这个程序的缺陷......?实际上它是两次打印最后一条记录。

#include <stdio.h>

int main(void)
{
  int accountNum;
  char name[30];
  double balance;
  int counter = 0;

  FILE *clientDataFile1;

  if( (clientDataFile1 = fopen("clients.txt", "r")) == NULL )
    printf("File could not be opened");
  else
  {
    printf("%-10s %-13s %s\n", "Account", "Name", "Balance");

    while( !feof(clientDataFile1) )
    {
      fscanf(clientDataFile1, "%d%s%lf", &accountNum, name, &balance);      
      printf( "%-10d%-13s%.2lf\n", accountNum, name, balance );
    }

    printf("\n\n\n");
    rewind(clientDataFile1);    
    counter++;
    fclose(clientDataFile1);
  }

  return 0;
}

这真的很痛苦。我尝试了很多次但这个漏洞无法捕捉。要么工作不清楚,要么Ubuntu 12.10或gcc对此负责。 帮助我....

4 个答案:

答案 0 :(得分:5)

你以一种看起来非常受初学者欢迎的方式使用feof(),但不幸的是仍然是错误的。

feof()的要点是在发生I / O错误后查询,如果由于文件末尾已到达而发生错误。 not 应该用于过早地决定文件是否已经结束。

只需执行读取直到失败。

while( fscanf(clientDataFile1, "%d%s%lf", &accountNum, name, &balance) == 3 )
{
    printf( "%-10d%-13s%.2lf\n", accountNum, name, balance );
}

答案 1 :(得分:4)

在阅读@unwind的答案之后,我很好奇feof()做了什么,以及为什么这会导致最后一条记录的双重打印。

cplusplus.com:“请注意,流的内部位置指示符可能指向下一个操作的文件结尾,但是,在操作尝试执行之前,可能无法设置文件结束指示符那时读。“

所以你到达EOF并打印最后一条记录,但feof()检查的标志尚未设置。然后,在循环的下一次迭代中,您执行fscanf由于过去EOF而失败。此失败导致标志被设置,使其成为循环的最后一次迭代。此迭代仍会打印已保存在accountnumnamebalance变量中的内容,因此您会看到最后一条记录两次。

答案 2 :(得分:1)

简短回答:你的while循环应如下所示:

while (!feof(clientDataFile1))
{
  if (EOF == fscanf(clientDataFile1, "%d%s%lf", &accountNum, name, &balance))
    break ;

  printf( "%-10d%-13s%.2lf\n", accountNum, name, balance );
}

答案 3 :(得分:0)

while(fscanf(clientDataFile,“%d%s%lf”,&amp; accountNum,name,&amp; balance)!= EOF )             printf(“%-10d%-13s%。2lf \ n”,accountNum,name,balance);

实际上EOF的值是-1而fscanf()返回的是输入变量的数量。因此,当fscanf()的值等于EOF(-1)时,表达式!=计算0,从而实现了while的中断。