std::fstream 一些经验

C++流与EOF
本文解析了C++中使用fstream流进行文件读取时eof()函数的行为特点,并通过实例说明了如何正确处理文件末尾判断,避免数据重复读取的问题。

在做实验的时候遇到这个问题,找原因的时候发现出处除了讲明原因,还举了例子,所以记下来。

其实在循环判断文件是否结束的时候可以直接就流输入放在循环条件那里,但是这里补充使用eof()的一些细节问题。其实这是关于到底什么时候标志位才会变化的问题。总结起来就是只有使用一次流变量来输入输出,标志位才会更新一次。

 

正文:

 

 

   fstream流的eof()  判断有点不合常理

 

 

   按正常逻辑来说,如果到了文件末尾的话 ,那eof()应返回真

 

   但是,c++输入输出流如何知道是否到末尾呢?

 

   原来是根据的是: 如果fin>>不能再读入数据了,才发现到了文件结尾,这时才给流设定文件结尾的标志,此后调用eof()时,才返回真。

 

 

   假设

 

   fin>>x; //此时文件刚好读完最后一个数据(将其保存在x中)

 

   但是, 这时 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

  

   http://topic.csdn.net/u/20091014/12/4182ffd1-055c-490e-bfc5-9b82a9004144.html?seed=588522249&r=60404137#r_60404137

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值