示例程序如下:
main(){
char s[100];
FILE * fp = fopen("./file","r");
while(1)
{
printf("the file point before fgets is %d\n",ftell(fp));
fgets(s,100,fp);
printf("the file point after fgets is %d\n",ftell(fp));
printf("%s",s);
if(feof(fp))
break;
}
fclose(fp);
}
文件file的内容如下:
hello world first
hello world second
程序的运行结果如下:
the file point before fgets is 0
the file point after fgets is 18
hello world first
the file point before fgets is 18
the file point after fgets is 37
hello world second
the file point before fgets is 37
the file point after fgets is 37
hello world second
为什么会出现两个"hello world second"呢?下面分析原因:
在分析之前,先看一下feof的解释: feof () 是一个检测文件是否结束的宏,当文件的结束标志被置位时,再次对文件进行任何读操作,都将返回此标志,直到使用rewind () 或关闭文件为止。同时,每一次输出都会使feof() 标志失效。
那什么时候,文件的结束标志才会置位呢? 通过测试,我发现,当文件当前指针位于文件末尾时(相当于fseek(fp,0,SEEK_END)),此时如果执行一次读操作,文件结束标志就会被设置(结束标志位于FILE结构中)。
fseek(fp,0,SEEK_END);
printf("the file point is :%d\n",ftell(fp));
printf("%c\n",fgetc(fp)); //if not do read operation, the end of file flag is not set
if(feof(fp))
printf("file end\n");
else
printf("not reach file end\n");
如果将上面的fgetc(fp)去调,就会发现显示的是"not reach file end"
现在回过来说,为什么出现两次“hello world second”。那是因为文件结束标识没有设置,而s指向的缓冲区保存了上次读的内容。当第三次读时,于是输出了上次的缓存区内容,此时文件结束标志设置,于是退出了循环。