出处: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