首页 > 编程知识 正文

编写一个打印eof值的程序,struct在c语言中是什么意思

时间:2023-05-05 01:02:33 阅读:116726 作者:1244

作者:海子来源: http://www.cn blogs.com/dolphin 0520 /

c语言文件操作分析(五)的EOF分析

在c语言中,有一个应该是众所周知的符号。 那是eof (结束文件),是文件结束符。 但是,这种理解往往不明确,在编写代码时经常发生错误,特别是在确定文件是否到达文件末尾时。

1 .什么是Eof?

用VC看EOF的定义是:

#定义Eof (-1 ) ) )。

EOF只是表示整形常数-1。 因此,很多人认为在文件的末尾存在该结束标志EOF,但这种想法是错误的。 其实在文件的末尾不存在这个标记。 那么,下一步怎么解释?

char ch; wile((ch=fgetc ) FP )!=EOF ) printf('%cn ',ch ); }

在本例中,用这样的代码判断是否读取到文档的末尾是在读取到EOF时结束操作。 这个理解是错误的。

/*

这一段不是原文的内容。 添加以补充这里的说明

例如,以下文本文件中的磁盘内容在文件末尾没有-1:

*/

让我们先看看函数fgetc的原型:

int fgetc (文件* FP );

实际上,在fgetc函数内部,每次都会读取1字节的数据。 然后,以unsigned或无符号类型处理该1字节数据,并将该1字节数据分配给一个int类型变量,并作为返回值返回。 因此,无论从文件读取什么数据,都将一个int类型变量指定为无符号类型,返回值不是负数。 例如,如果读取的是数据0xFA,则处理时没有符号,因此将0xFA代入int类型变量时,int类型变量的高位将被0填充(为什么填充0与程序集语言中的符号扩展类似)。 后述)。 其结果为0X00 00 00 FA,并不总是负数。 读取到文件末尾时,将无法读取数据

上面的代码有很大的限制。 因为只能判断是否到达了文本文件的末尾,无法正确判断二进制文件。 通常,文本文件无法读取-1(0xff )数据,因此可以判断。 但是,根据二进制文件,1字节的数据为0xFF的可能性较高,返回值在这个点是-1,但是在这个点还没有到达文件末尾,会做出错误的判断。

那么有解决的方法吗? ch可以定义为int型即可。

比较一下下面的程序和上面的程序运行时的区别。

int ch; wile((ch=fgetc ) FP )!=EOF ) printf('%cn ',ch ); }

假设读取到文件中的数据为0xFA。

上一个程序的执行过程是:

如果先将0xFA代入1个int型变量中,则此时a为0x 00 00 00 FA。 如果将返回值a返回变量ch,则ch为char型,只有8位,因此如果只将a的低位8位代入ch,则此时ch为0xFA,ch被视为带符号。 此时,ch的值一定为负数。

如果将ch定义为int类型,则运行进程为:

如果先将0xFA代入一个int型变量,则此时a为0x 00 00 00 FA,如果将返回值a返回变量ch,则ch也为int型,因此ch与0x 00 00 00 FA为正数,执行两个程序得到的结果完全不同。

看看读取的数据为0x FF (此时未到达文件末尾)时会产生什么样的结果。

在ch为char型情况下,在返回返回值0x 00 00 00 FF时,若将低位8比特分配给ch,则此时ch为-1,误判定为到达了文件末尾;

另一方面,ch为int型时,如果返回返回值0x 00 00 00 FF,则ch的值为0x 00 00 00 FF,ch不是-1,不会误判定为文件末尾。

(当然,上述内容必须在读取无误的情况下成立)

所以很多时候会使用函数feof。

二. feof

EOF函数的原型是

int feof (文件* FP );

如果到达文件末尾,则返回非零值,否则返回0。

用VC看feof函数的定义:

#define _IOEOF0x0010

#definefeof(_stream ) ) _stream )-_flag _IOEOF () ) ) ) ) ) ) )。

可知判断feof函数是否到达文件末尾与名为_flag的标志有关。

看看这个程序:

#include#includeintmain(void ) { FILE *fp; int ch; if () FP=fopen('test.txt ',' w ' ) )==NULL ) (printf ) ) cannotopenfilen ); 退出(0;

} for(ch=65;ch<=70;ch++) { fputc(ch,fp); } rewind(fp); while(feof(fp)==0) { ch=fgetc(fp); printf("%0Xn",ch); } fclose(fp); return 0;}

执行结果是:

41 42 43 44 45 46 FFFFFFFF Press any key to continue

为什么最后打印结果会多打印一个FFFFFFFF?不是只往文件中写入了数据65-70么?

先看一下C++ Reference中关于feof函数的描述(C++ Reference是一个比较好的网站,里面是关于C++所有库函数的描述,网址在博客首页的链接中有,http://www.cplusplus.com/reference/):

Checks whether the End-of-File indicator associated with stream is set, returning a value different from zero if it is. This indicator is generally set by a previous operation on the stream that reached the End-of-File.

从描述中可知,只有当与文件关联的流到达文件末尾时,此时若再进行读取操作,文件结束的标志(上面所述的_flag)才会被重新置位。

因此在上述程序中,当读取完最后一个字节的数据后,文件结束标志并没有被置位,只有当位置指针到达末尾时,再发生读取操作时,而此时又没有数据可供读取,因此返回-1,所以打印出的结果中会多一个FFFFFFFF,在这之后才会将_flag重新置位,此时feof函数才能检测出已经到达了文件末尾。

那么可以通过下面的办法解决这个问题:

ch=fgetc(fp); while(feof(fp)==0) { printf("%0Xn",ch); ch=fgetc(fp); }

这样就不会多打印一个FFFFFFFF了。

在上面提到汇编语言中符号扩展的问题,其实在C语言中属于数据类型转换的范畴。下面简要说明一下:

符号扩展只针对将字长小的数据赋给字长大的数据时存在,若是字长大的数据赋给字长小的数据,取低位即可。

下面看一段程序:

#includeint main(void){ unsigned char ch1=0XFF; char ch2=0XFF; char ch3=0X73; int a=ch1; int b=ch2; int c=ch3; printf("%dn%dn%dn",a,b,c); return 0;}

执行结果为:

255

-1

115

原因是由于ch1、ch2、ch3都是char型变量,只占一个字节,区别在于ch1是无符号的,在将ch1赋值给a时,ch1是看做无符号数据进行处理的,那么在填充a的高位是用0去填充;而对于ch2和ch3都是有符号的,那么在填充高位时就要注意了,若ch2的最高位为0,那么表示ch2是正数,此时填充高位用0填充,而若ch2的最高位为1,则填充高位数据用1填充。

如程序执行的结果所示,由于ch2的最高位为1,那么在填充b的高位的时候会用1去填充,那么b为0X FF FF FF FF;而ch3的最高位为0,那么填充c的高位用0填充,所以c的值为0x 00 00 00 73.

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。