fgets()重复读取最后⼀⾏的分析及解决⽅法      使⽤ fgets() 读取⼀个⽂本⽂件的时候,如果读取的 ⽅法不恰当,就有可能造成重复读取最后⼀⾏的问题。具体如下。
fgets和fgetc的区别(1) 在 Windows 平台上, 假设有 ,内容如下:
this is line 1
this is line 2
this is line 3
this 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 下,执⾏结果:
实验表明,这种读取⽅法在两种平台都能正确地读取。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。