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的值仍爲最後一個整數的值,所以將再次讀取該值。若是將下面一句spa

getc(fp)!=EOF

改成!feof(fp),則問題仍會出現,緣由同上。code

代碼解決之道

    正確的作法應該是下面一段代碼:
 get

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語言,感謝計算機!
博客

相關文章
相關標籤/搜索