为什么fgets()会读取文件最后一行两次?

参考:点击打开链接

为什么fgets()会读取文件最后一行两次?  

2012-09-05 03:39:49|  分类: C++|举报|字号 订阅

我们在读取文件时,书中经常提到的逻辑是这样的,但这是错误的!

while(!feof(Fp))
{

fgets(readLine,10000,Fp);

//do something.

}

 

原因在于feof()只有在你尝试读取文件结尾之后,才会返回true。也就是说,feof()之解释上次文件读写是否到达结尾,而不是下一次。

 

所以正确的逻辑应该是这样的。

while(true) {
fgets(readLine,10000,Fp);
if( feof(Fp) ) break;
do something.
}



发信站: 北邮人论坛 (Thu Dec  2 18:02:45 2010), 站内 
  
【 在 RaulSpain007 的大作中提到: 】 
bool Token()  
{  
      ifstream in;  
      string token;  
      in.open("Token.txt", ios::in);  
      if(in.good()) 
      {  
         while(!in.eof()) //这里有问题,如果最后一个7后面有个空格或回车什么的,读完最后一个7的时候,就不会到eof 
         {  
             in >> token; //这时候,读取操作俨然失败,因为7后面没有数了,于是token保持上次值不变,仍然为7 
             TokenVector.push_back(token); //于是7就又一次被加到vector中了 
         }  
         in.close();  
         return true;  
      }  
      else  
          cout << "Can't find Token.txt." << endl;  
      return false;  
}  
  
解决办法: 
bool Token()  
{  
      ifstream in;  
      string token;  
      in.open("Token.txt", ios::in);  
      if(in.good()) 
      {  
          while(in >> token) //这句话等价于:while(in>>token, in) 
         //而C++标准规定,stream类型能够强制转化为void*类型, 
         //(void*)(stream)的值为:stream.fail() ? 0值 : 非0值。 
         //所以上面的语句又间接等价于:while(in>>token,!in.fail()) 
         {  
             TokenVector.push_back(token); 
         }  
         in.close();  
         return true;  
      }  
      else  
          cout << "Can't find Token.txt." << endl;  
      return false;  
}  
  
  
请注意,下面的代码是错的: 
bool Token()  
{  
      ifstream in;  
      string token;  
      in.open("Token.txt", ios::in);  
      if(in.good()) 
      {  
         while(!in.fail()) //第一次读完7后,读取操作成功,fail()为假,继续循环 
         {  
             in >> token; //此时,读取操作失败,token不变,仍为上一个7 
             TokenVector.push_back(token); //这个7就又被哀怨地加到vector中了! 
         }  
         in.close();  
         return true;  
      }  
      else  
          cout << "Can't find Token.txt." << endl;  
      return false;  


使用流的一个经验是,要在读取操作之后立即判断是否成功,成功则读取数据有效,不成功则读取数据无效。
上面的解决办法便是遵守了这条规则。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值