EOF和feof

 

EOF和feof

在C语言中feof函数用来判断是否到达文件的末尾。如果要使用此函数必须引入stdio.h头文件。

函数形式:int feof(FILE *stream); 

函数返回值:如果文件指针到达文件末尾则反回一个非零值,否则为0;

下面用一个实例来说明:

#include <stdio.h>  

#include <stdlib.h>  

int main(void)

{

FILE *fp;

if((fp=fopen("test.txt", "r"))==NULL)

{

printf("Cannot open file.\n");

exit(1);

while(!feof(fp)) 

char ch = getc(fp); 

printf("%c",ch); 

}

fclose(fp);

return 0;

}

判断文件结束有两种方法:EOF和feof()
查看stdio.h可以看到如下定义:
#define EOF (-1)

#define _IOEOF 0x0010
#define feof(_stream) ((_stream)->_flag & _IOEOF)

由此可以看出,这两种方式的原理是不同的。
有人说EOF只能用于文本文件,其实不然,还要看定义的变量的类型。下面这段程序对文本文件和二进制文件都可以:

int c;

while((c=fgetc(fp)) != EOF)

{

printf("%X\n", c); 

}
如果读到了FF,由于c定义为int型,所以实际上c=0x000000FF,不等于EOF(-1=0xFFFFFFFF),因此不会误判为文件结尾。但是如果把c定义为char类型,就有可能产生混淆了。
char c;

while((c=fgetc(fp)) != EOF)

{

printf("%X\n", c); 

}

fclose(fp);
因为文本文件中存储的是ASCII码,而ASCII码中FF代表空值(blank),一般不使用,所以如果读文件返回了FF,说明已经到了文本文件的结尾。但是如果是二进制文件,其中可能会包含FF,因此不能把读到EOF作为文件结束的条件,此时只能用feof()函数。

在VC里,只有当文件位置指针(fp->_ptr)到了文件末尾,然后再发生读/写操作时,标志位(fp->_flag)才会被置为含有_IOEOF。然后再调用feof(),才会得到文件结束的信息。因此,如果运行如下程序:
char c;

while(!feof(fp))

{

c = fgetc(fp);

printf("%X\n", c);

}
会发现多输出了一个FF,原因就是在读完最后一个字符后,fp->flag仍然没有被置为_IOEOF,因而feof()仍然没有探测到文件结尾。直到再次调用fgetc()执行读操作,feof()才能探测到文件结尾。这样就多输出了一个-1(即FF)。
正确的写法应该是:
char c;

c = fgetc(fp);

while(!feof(fp))

{

printf("%X\n", c); 

c = fgetc(fp);

注意这是正确的解法,谭浩强的书里有一个错误就是因为没有注意到这个问题,下面请看

这个文件复制程序代码,红色画线表示错误

错解:注意红色部分

#include<stdio.h>

#include<stdlib.h>

void main()

FILE *in,*out;

if((in=fopen("in.txt","r"))==NULL)   

{      

printf("cannot open file ");     

exit(0);  

}

if((out=fopen("out.txt","w"))==NULL) 

{     

printf("cannot open file ");     

exit(0);  

}  

while(!feof(in))

{      

fputc(fgetc(in),out);

}

fclose(in);

fclose(out);

}

看正确的代码:

#include<stdio.h>

#include<stdlib.h>

void main()

FILE *in,*out;

char ch;

if((in=fopen("in.txt","r"))==NULL)  

{    

printf("cannot open file ");

exit(0); 

}

if((out=fopen("out.txt","w"))==NULL)

{  

printf("cannot open file ");      

exit(0);

}  

ch=fgetc(in);  

while(!feof(in))

{    

fputc(ch,out);  

ch=fgetc(in);

}   

/*while((ch=fgetc(in))!=EOF)

fputc(ch,out);这个代码也是正确的ch字符变量时只能应用于文本文件。*/

fclose(in);

fclose(out);

}

这么说其实feof()是可以用EOF来代替的?不是,这里还有一个问题。fgetc返回-1时,有两种情况:读到文件结尾或是读取错误。因此我们无法确信文件已经结束, 因为可能是读取错误! 这时我们需要feof()。

你可能感兴趣的:(职场,休闲,eof,feof)