许多C语言初学者都发现,在使用feof函数判断文件指针是否到末尾时,常出现多读一个字符的问题。有初学者为避免此问题,先用fgetc()吸取字符,再以该字符是否为EOF(即返回值-1)来判断文件指针是否到末尾。但若二进制文件末正好出现-1,编译系统就无法辨别是否为结束标志。(文本文件中字符ASCII码不可能为-1,不会出现问题)
1.我们首先解释一下feof()多读字符的原因
假设现在文件指针指向文件末(最后有效字符再往后一位)
用feof()判断时,flag却还保持不变,即feof()返回值仍然是0
于是代码
......
FILE *in;
......
while(!feof(in))
{
//这其中的语句仍然会被执行
}
只有当这次多余的循环结束时,flag才会改变,即feof()返回值变为1
若语句中有fgetc()、fputc()等语句就会多读或写一个字符,但这不是我们希望得到的结果
2.解决方案
【1】更好理解,便于记忆,但存在弊端
......
FILE *in;
char ch;
......
while(!feof(in)) //不为文件末就不断循环
{
ch=fgetc(in); //每次判断当前指针位置处字符是否为NULL(空),即判断返回值是否为-1
if(ch != -1)
{
//语句 //若不返回-1,即该字符有效,执行语句
}
}
弊端:处理二进制文件时,正好遇到-1,语句就不被执行,会漏读。但这种情况出现概率极低
【2】有技巧,但很完美
......
FILE *in;
char ch;
......
ch=fgetc(in); //#1
while(!feof(in))
{
// 语句;
ch=fgetc(in);
}
当执行完语句#1后,指针已自动向后移一位,feof()判断的是后一位的情况。
当吸走最后一个有效字符后,指针移到最后有效字符再往后一位,由前面分析已知,feof()判断结果为0,会再执行循环一次,正好处理完最后一个有效字符后循环结束。
附:其实根本没有文件结束符EOF,他仅仅与-1等价(在stdio.h文件中#define EOF -1)
FILE *in;
char ch;
(ch = fgetc(in))=EOF;
的含义仅仅是fgetc()未读到字符,失败,返回-1,赋给ch,ch=EOF
希望以上的内容对您有所帮助!