判断一个文件的读取是否结束,很多人,会想到用feof函数来判定,的确需要用到这个函数,但是仅仅靠这个函数是不够的。
错误用法:
#include<stdio.h>
int main()
{
FILE* pf = fopen("2128.txt","r");
if(pf == NULL)
{
perror("pf");
}
if(feof(pf))
{
printf("end of file");
}
return 0;
}
运行结果:
实际上文件无内容,按理应该输出 end of file;
先看函数原型:
返回值:(搞清楚他的返回值含义就知道怎么使用了)
(读取的)当前位置不是文件末尾(可以理解为EOF)的时候返回0;其实就算读取到了EOF也是返回0;
当要首次尝试读取文件末尾(EOF)后面的内容的时候返回非零值;(所以要想利用feof函数判定文件读取结束的前提是已经读取到了EOF,我们可以理解为只有feof函数才能读取EOF后面的内容,所以上面那个错误的用法中,读的是EOF,返回值为0,并不是EOF后面的内容)
这里解释一下文件结束符EOF,它只是一个stdio.h里面定义的一个标识符常量-1,并不是真正存在于文件中。比如一个空文件(无任何字符),我们读取一个字符,系统会默认给读取的内容赋值EOF(-1)。
但是有些文件读取函数读取失败的时候也会返回EOF;比如文本文件字符读取函数fgetc,二进制文件读取函数fread,它们读取失败的时候也返回EOF,因此,我们读取到了EOF后,需要判断是真正读到了文件末尾(即文件读取结束),还是读取函数发生了错误而返回的EOF;
文本文件读取结束的判定:
#include<stdio.h>
int main()
{
//char a[20];
int c = 0;
FILE* pf = fopen("2128.txt","r");
if( pf == NULL)
{
perror("pf");
return 0;
}
while((c = fgetc(pf))!=EOF)//读取到了EOF跳出循环
{
putchar(c);
}
//判定是否是fgetc函数读取出错,出错返回非零值;
if(ferror(pf))
perror("pf");
//fgetc函数没出错,正常读取到了EOF,这时才能用feof定论
else if(feof(pf))
printf("end of file\n");
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
注意while循环里面的条件(c = fgetc(pf))!=EOF,读到EOF后跳出循环,只不过没有打印,此时可以理解光标已经指向了EOF后面的内容,所以最后面调用feof函数的时候,满足其返回值里面的说明:即尝试读取EOF后面的内容的时候返回非零值,因此我们先用ferror函数过滤掉fetc函数读取失败返回EOF的情况,再用feof函数来判定文件读取结束。(fetc函数读取发生错误ferror返回非零值。)
二进制文件读取结束的判定也是相同的道理,这里不再赘述。