出處:http://blog.csdn.net/shuilan0066/article/details/4669451html
在作實驗的時候遇到這個問題,找緣由的時候發現出處除了講明緣由,還舉了例子,因此記下來。ios
其實在循環判斷文件是否結束的時候能夠直接就流輸入放在循環條件那裏,可是這裏補充使用eof()的一些細節問題。其實這是關於到底何時標誌位纔會變化的問題。總結起來就是隻有使用一次流變量來輸入輸出,標誌位纔會更新一次。c++
正文:ui
fstream流的eof() 判斷有點不合常理spa
按正常邏輯來講,若是到了文件末尾的話 ,那eof()應返回真.net
可是,c++輸入輸出流如何知道是否到末尾呢?code
原來是根據的是: 若是fin>>不能再讀入數據了,才發現到了文件結尾,這時纔給流設定文件結尾的標誌,此後調用eof()時,才返回真。htm
假設blog
fin>>x; //此時文件恰好讀完最後一個數據(將其保存在x中)get
可是, 這時 fin.eof()仍未假 由於,fin流的標誌eofbit是FALSE, fin流此時認爲文件尚未到末尾
只有當流再次讀寫時
fin>>x; 發現已無可讀寫數據,此時流才知道到達告終尾,這時纔將標誌eofbit修改成TRUE
此時流才知道了文件到底了末尾
也就是說,eof在讀取完最後一個數據後,還是False,
當再次試圖讀一個數據時,因爲發現沒數據可讀了 才知道到末尾了,此時才修改標誌,eof變爲TRUE
如下例子:
1 ifstream fin("D://line.txt"); 2 3 ofstream fout("D://T_line.txt",ios::trunc); 4 5 6 list<tag_Point> test_list; 7 8 tag_Point test; 9 10 11 12 while (!fin.eof()) 13 { 14 15 16 17 fin>>test.x; 18 fin>>test.y; 19 fin>>test.z; 20 21 22 23 24 test_list.push_back(test); 25 26 27 } 28 29 fin.close(); 30 31
在運行時 發現 test_list中的數據比文本中的數據多一行,也就是 文本中最後一行的數據寫了兩遍
始終沒法理解
如今明白了:》
再讀完最後一行後,
由於fin.eof()仍爲假, 因此會繼續while循環
當執行到while的第一個語句 fin>>test.x時,發現無可讀數據了,此時修改流屬性,fin.eof ()變爲TRUE
再執行 fin>>test.y; fin>>test.z;時,由於已經到文件末尾了 ,因此 test保留了上次的值,也即test中的值爲變,仍是文本最後一行
的數據
此時再push_back(test),壓入列表的還是最後一行數據
由此致使了,列表中的數據比文本中的數據多一行
---------------------
知道了緣由 ,便很好做出修改了
修改成:
1 while ( fin>>test.x&&fin>>test.y&& fin>>test.z) 2 { 3 4 5 test_list.push_back(test); 6 7 8 } 9 10 fin.close();
這樣便沒問題了 ,當讀取完最後一行數據後,將其放入列表中,此時判斷while條件,也就是再次讀取數據,發現無數據可讀,讀取不成功 fin>>test.x返回False 由此結束循環。
參考資料:
http://zhidao.baidu.com/question/121339522.html?fr=im