feof和EOF的字符被重复读取问题的思考

void main()
{
  PNode pNode;
  FILE *fp=fopen("1.txt","r");
  pNode=Create(i);
  while(getc(fp)!=EOF) {
    int i;
    fscanf(fp,"%d",&i);
    pNode=Add(i,pNode);
  }
  fclose(fp);
  Print(pNode);
}

(问题源码如上所示)

问题介绍

    我在温习C语言时,准备尝试编写单链表的结构,但是写到上面一段代码,运行后发现,文件的最后一个字符被重复读取了,焦头烂脑思考了一会儿,并且尝试搜集资料,写了这个博客。

问题思考

    这个问题根源在文件读取上,因为我尝试了直接向链表中添加数据是没有任何问题的。而本程序使用了两个文件读取函数,即getc和fscanf,这两个函数的交错使用在一定程度上是程序结构有点混乱,这可能是我当时编程的时候没有用心思考造成的。

    如果文件自身没有设置EOF的话,我们的getc函数遇到'\0'之后,将设置为EOF,再进入循环体一次,而fscanf已经读取不到有效字符了,因此返回EOF,但是此时i的值仍为最后一个整数的值,因此将再次读取该值。如果将下面一句

getc(fp)!=EOF

改为!feof(fp),则问题仍会出现,原因同上。

代码解决之道

    正确的做法应该是下面一段代码:
 

PNode pNode;
  //从文件中读取数据并添加到链表中
  FILE *fp=fopen("1.txt","r");
  int count=0;
  int i;
  pNode=Create();
  while(fscanf(fp,"%d",&i)!=-1) {
    pNode=Add(i,pNode);
  }
  fclose(fp);
  Print(pNode);

这样的话,重复读取字符的问题就不会出现了。因为此时会直接判断是否是有效字符,若不是,直接退出while循环,因此最后一个字符只会被读取一次。

总结

    用C语言实现数据结构确实能够学到很多东西,越是底层的语言,越能锻炼我的代码能力。本次尝试自己完全独立编写单链表的基本操作,基本上可以实现感谢C语言,感谢计算机!

你可能感兴趣的:(C语言,文件读取,eof,feof)