使用fgets函数返回值而不是feof

今天在调试程序的时候,发现cevtor中多了一个数据。函数如下:

隐藏行号 复制代码 原始代码。
  1. void create_testcase::read_districtfiles()
    
  2. {
    
  3.     tstring::size_type pos=m_str_logpath.rfind(_T('//'));
    
  4.     if (tstring::npos==pos) return;
    
  5.  
  6.     tstring str_name = m_str_logpath+m_str_logpath.substr(pos);
    
  7.     FILE *pinfile = _tfopen(str_name.c_str(), _T("rt+, ccs=UTF-8"));
    
  8.     if (NULL==pinfile) return;
    
  9.  
  10.     TCHAR linex[MAX_PATH]=_T("");
    
  11.     tstring str_line, str_district, str_count;
    
  12.     while (!feof(pinfile))
    
  13.     {
    
  14.         _fgetts(linex, MAX_PATH, pinfile);
    
  15.         str_line = tstring(linex);
    
  16.         ...;
    
  17.         m_name_vector.push_back(tspair(_ttoi(str_count.c_str()), str_district));
    
  18.     }
    
  19.     fclose(pinfile);
    
  20. }
    
<script language="javascript"> function CopyCode(key){var codeElement=null;var trElements=document.all.tags("ol");var i;for(i=0;i 加断点看看,最后一个元素重复了,再追,发现原来是文件最后一行被fgets()函数读了两遍。

 
查MSDN,feof,有这么一段话:
“The feof routine (implemented both as a function and as a macro) determines whether the end of stream has been passed. When the end of file is passed, read operations return an end-of-file indicator until the stream is closed or until rewind, fsetpos, fseek, or clearerr is called against it.

For example, if a file contains 10 bytes and you read 10 bytes from the file, feof will return 0 because, even though the file pointer is at the end of the file, you have not attempted to read beyond the end. Only after you try to read an 11th byte will feof return a nonzero value.”

注意,上面说的是“the end of stream has been passed, read operations return an end-of-file indicator”,也就是说,只有文件位置指针越过文件结尾以后,read操作才会返回e-o-f的指示符。

 

 

测试1. 创建一个空的txt文件,并使用下面程序测试:

隐藏行号 复制代码 测试代码1。
  1. void TestFun1()
    
  2. {
    
  3.     FILE *pinfile = _tfopen(_T("f://12.txt"), _T("rt+"));
    
  4.     if (NULL==pinfile) return;
    
  5.  
  6.     while (!feof(pinfile))
    
  7.     {
    
  8.         MessageBox(NULL, _T("test"), _T("debug"), 0);
    
  9.     }
    
  10.     fclose(pinfile);
    
  11. }
    

结果:啊哦,进入死循环了。
分析:文件位置指针一直没有越过文件结尾,feof一直返回为0,所以进入死循环。

 

 

测试2. 程序更改为:

隐藏行号 复制代码 测试代码2。
  1. void TestFun2()
    
  2. {
    
  3.     FILE *pinfile = _tfopen(_T("f://12.txt"), _T("rt+"));
    
  4.     if (NULL==pinfile) return;
    
  5.  
  6.     TCHAR szTest[MAX_PATH]=_T("");
    
  7.     while (!feof(pinfile))
    
  8.     {
    
  9.         _fgetts(szTest, MAX_PATH, pinfile);
    
  10.         MessageBox(NULL, szTest, _T("debug"), 0);
    
  11.     }
    
  12.     fclose(pinfile);
    
  13. }
    
<script language="javascript"> function CopyCode(key){var codeElement=null;var trElements=document.all.tags("ol");var i;for(i=0;i 结果:弹出一个对话框,内容为空。
分析:fgets函数读MAX_PATH-1个字符以后,文件位置指针已经后移,并且越过了文件结尾,所以下一次调用feof时,返回非0值。

 

 

测试3. 在txt文件中添加数字“1”,TestFun2()函数测试。
结果:只弹出一个对话框,内容为1。
分析:fgets函数读MAX_PATH-1个字符以后,文件位置指针已经后移,并且越过了文件结尾,所以下一次调用feof时,返回非0值。

 

 

测试4. 在txt文件中1后面加上回车符,TestFun2()函数测试。
结果:弹出两个对话框,内容都为1。
分析:fgets第一次,遇到换行符,停止,此时文件位置指针已经到达文件尾部,但是还没有越过,所以,while没有退出, 因为文件位置指针已经到文件尾部,所以第二次fgets没有读到任何数据。

 

 

测试5. 文件内容不变,使用下面程序测试

隐藏行号 复制代码 测试代码2。
  1. void TestFun3()
    
  2. {
    
  3.     FILE *pinfile = _tfopen(_T("f://12.txt"), _T("rt+"));
    
  4.     if (NULL==pinfile) return;
    
  5.  
  6.     TCHAR szTest[MAX_PATH]=_T("");
    
  7.     while (!feof(pinfile))
    
  8.     {
    
  9.         if (NULL!=_fgetts(szTest, MAX_PATH, pinfile))
    
  10.             MessageBox(NULL, szTest, _T("debug"), 0);
    
  11.         else
    
  12.             MessageBox(NULL, _T("NULL"), _T("debug"), 0);
    
  13.     }
    
  14.     fclose(pinfile);
    
  15. }
    
<script language="javascript"> function CopyCode(key){var codeElement=null;var trElements=document.all.tags("ol");var i;for(i=0;i 结果:弹出两个对话框,内容分别为“1”和“NULL”。
分析:以上结果与测试4的分析是一致的。

 

 

测试6. 文件内容不变,使用下面程序测试

隐藏行号 复制代码 测试代码2。
  1. void TestFun4()
    
  2. {
    
  3.     FILE *pinfile = _tfopen(_T("f://12.txt"), _T("rt+"));
    
  4.     if (NULL==pinfile) return;
    
  5.  
  6.     TCHAR szTest[MAX_PATH]=_T("");
    
  7.     while (NULL!=_fgetts(szTest, MAX_PATH, pinfile))
    
  8.     {
    
  9.         MessageBox(NULL, szTest, _T("debug"), 0);
    
  10.     }
    
  11.     fclose(pinfile);
    
  12. }
    
<script language="javascript"> function CopyCode(key){var codeElement=null;var trElements=document.all.tags("ol");var i;for(i=0;i 结果:只弹出一个对话框,内容为“1”。

 

总结:所以,我们在整行得去文件的时候,最好采用fgets函数的返回值来控制while循环而不是采用fefo函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值