1 feof()函数
1.1 函数原型
feof():检测指定文件流stream的文件结束标识,函数原型如下:
int feof(FILE *stream);
1.2 参数
feof()函数只有一个参数stream:
- 参数stream是一个指向FILE类型结构的指针(fopen()函数的返回值)。
1.3 返回值
feof()函数的返回值类型为int型:
- 文件流stream的文件结束标识已经设置,返回非0值表示已经到达文件末尾;
- 文件流stream的文件结束标识没有设置,返回0值表示还没有到达文件末尾。
C语言标准描述如下:
1. nonzero value if the end of the stream has been reached, otherwise 0
1.4 检测机制
feof()函数是通过检查文件流的文件结束标识来确定是否已经到达文件末尾,而不是直接检查文件的位置指示符。
具体地说,当读文件函数试图从文件中读取数据但没有成功时,文件流的文件结束标识会被设置。
当调用feof()函数时,它会检查文件流的文件结束标识是否已经设置,如果已经设置,则返回非零值表示已经到达文件末尾;如果没有设置,则返回零表示还没有到达文件末尾。
需要注意的是,feof()函数只有在读文件操作时才能检测到文件流的文件结束标识,因为写文件操作不会引发文件结束标识的设置。
在读取文件时,常用feof()函数来检测是否已经读到文件末尾。
特别说明:
对于文本文件,在文件末尾有一个隐藏的文件结束符EOF,EOF被定义在stdio.h函数库中,其值为-1,因为任何字符的ASCII码值都不是-1。
3 示例
3.1 示例1(重点关注)
使用feof()函数检测文本文件是否为空,示例代码如下所示:
int main(void)
{
//
FILE* fp;
//打开文件
fp = fopen("1.txt", "r");
//第一次判断
if (feof(fp))
{
printf("文件为空\n");
}
else
{
printf("文件不为空\n");
}
printf("ftell(fp) = %ld\n", ftell(fp));
printf("feof(fp) = %d\n\n", feof(fp));
//第二次判断
fgetc(fp);
if (feof(fp))
{
printf("文件为空\n");
}
else
{
printf("文件不为空\n");
}
printf("ftell(fp) = %ld\n", ftell(fp));
printf("feof(fp) = %d\n\n", feof(fp));
//
fclose(fp);
//
return 0;
}
代码运行结果如下图所示:
代码及运行结果分析如下:
- 文件是空文件,即只包含文件结束符EOF;
- 通过比较两次判断发现:(1)因为是空文件,所以文件位置指示符始终处在EOF的位置,ftell=0;(2)读文件之前,feof=0,读文件之后,feof=1,说明必须将EOF读取并判断后方能知道已经读到文件末尾,文件位置指示符在指向EOF之初,并不知道其已处在文件末尾的位置上。
3.2 示例2
使用fgets()函数读文本文件,使用feof()函数检测文件末尾,示例代码如下所示:
#define BUFSZ 100
int main()
{
//
char buf[BUFSZ] = { 0 };
FILE* fp;
//
if ((fp = fopen("hello.c", "r")) == NULL)
{
printf("Failed to open file.\n");
exit(1);
}
//
while (feof(fp) == 0)
{
fgets(buf, BUFSZ, fp);
printf("%s", buf);
}
//
fclose(fp);
//
printf("\n");
return 0;
}
代码运行结果如下所示: