fgets()重复读取最后一行的分析及解决方法
来源:互联网 发布:c#仓库管理系统源码 编辑:程序博客网 时间:2024/05/16 13:34
使用 fgets() 读取一个文本文件的时候,如果读取的 方法不恰当,就有可能造成重复读取最后一行的问题。具体如下。
(1) 在 Windows 平台上, 假设有 test.txt ,内容如下:
this is line 1this is line 2this is line 3this is line 4
使用传统的读取方法:
while( ! feof(fp) ){char tmp[100] ;fgets( tmp , 100 , fp );cout<<tmp<<endl;}
结果如下:
然而,换成 Linux 平台,就有不同的运行结果,如下:
(2)我们使用另一种读取方法:
/* 改进的读取txt文件的方式 */while( true ){char tmp[100];fgets( tmp , 100 , fp );if( feof(fp) )break;cout<<tmp<<endl;}
在 Windows平台上,运行结果如下:
很明显,最后一行没有被读取。
换成 Linux 平台,再次执行,结果如下:
(3) 现象原因分析
引用网上大牛的解释:
feof是ANSI标准定义的:在遇到文件结束时返回非0值。
对于象DOS系统,这比较方便。因为文件有明确的结束标志EOF。
对于UNIX,就稍微麻烦一点。因为文件没有结束标志,只有通过当前指针和文件长度来判断文件是否结束。当 read 时,先调用trap进入核心态,由FILE->;ile->;inode,取得文件的物理地址,然后取得文件的剩余的长度,比较该长度是否为0,如果为0则置文件结束标志;如果不为0,则比较该长度和要读的长度,取其中的小值,并将文件内容读入用户地址。
具体到我们所遇到的现象就比较清晰了,读文件最后一行的fgets(也是调用read的)被调用的时候,该文件的剩余长度不为0,所以不置文件结束标志。而再fgets时,文件的剩余长度为0,文件结束标志被置且马上返回。
(4)兼容 windows 和 Linux 的文件读取方式
分析了现象和原因,最后给出一种在Windows和Linux上都能够正确读取文本的方法。
/* 统一的的读取txt文件的方式 */char tmp[100] ;while( fgets(tmp , 100 , fp ) != NULL ){cout<<tmp<<endl;}
在 Windows 下,执行结果:
在 Linux 下,执行结果:
实验表明,这种读取方法在两种平台都能正确地读取。
参考资料:http://stackoverflow.com/questions/14615671/whats-the-real-reason-to-not-use-the-eof-bit-as-our-stream-extraction-condition
- fgets()重复读取最后一行的分析及解决方法
- fgets重复读取最后一行,都是feof惹的祸
- fgets() -- 读取文件的一行
- 在C++ 重复读取文件中的最后一行的解决办法
- 为什么fgets()会读取文件最后一行两次?
- fgets读取一行数据
- fgets()读取一行数据
- fgets()读取一行数据
- C语言文件操作之--读取文件最后一行(通过fgets完成)
- plsql游标最后一行重复的问题
- fgets读取文本内容的一行,如何去掉回车符
- php读取文件一行数据的函数fgets和fgetss
- 读取一个文本文件的最后一行
- VC++读取文件的最后一行
- python 读取文件的最后一行
- c++读取文件的最后一行
- Delphi读取文本文件的最后一行
- c++文件读取最后一行读取两次的问题
- 一个介绍GPU历史以及各个参数具体意义的好网站
- 清除所有文本框的值
- Linux 文件权限
- Android性能优化之加快应用启动速度
- Maven+Spring+Spring MVC+MyBatis+MySQL,搭建SSM框架
- fgets()重复读取最后一行的分析及解决方法
- jni搭建
- 【HttpClient4.5中文教程】【第二章 :连接管理】2.4---2.8
- android adb启动程序
- python中程序运行计时的三种方式
- Linux 文件查看命令
- 并查集及其在最小生成树中的应用
- 常见电脑蓝屏错误代码解析
- TIP: system errno 12 Cannot allocate memory