我在Windows上编程C(系统语言是日语),我有关于二进制文件和ascii文件的EOF的问题.
我上周问过这个问题,一个善良的人帮助了我,但我仍然无法理解程序在读取二进制文件或ascii文件时的工作原理.
我做了以下测试:
测试1:
int oneChar;
iFile = fopen("myFile.tar.gz", "rb");
while ((oneChar = fgetc(iFile)) != EOF) {
printf("%d ", oneChar);
}
Run Code Online (Sandbox Code Playgroud)
测试2:
int oneChar;
iFile = fopen("myFile.tar.gz", "r");
while ((oneChar = fgetc(iFile)) != EOF) {
printf("%d ", oneChar);
}
Run Code Online (Sandbox Code Playgroud)
在test1的情况下,对二进制文件和ascii文件都很有效.但是在test2中,程序在二进制文件中遇到0x1A时停止读取.(这是否意味着1A == EOF?)ASCII表告诉我1A是一个名为substitute的控制字符(无论这意味着什么......)然而,当我printf("%d",EOF)时,它给了我- 1 ...
我还发现这个问题告诉我操作系统确切地知道文件的结束位置,所以我真的不需要在文件中找到EOF,因为EOF超出了一个字节的范围(大概是1A?)
有人可以为我清理一下吗?提前致谢.
这是一个文本文件,特定于Windows的绝招:SUB字符,这是由代表Ctrl+ Z序列,被解释为EOF通过fgetc.但是,您不必1A在文本文件中获得EOF回复fgetc,一旦到达文件的实际结尾,EOF将返回.
标准没有定义1A为char表示的值EOF.EOF类型为常量int,负值超出范围unsigned char.实际上,fgetc返回an 的原因int不是char让它返回一个特殊值EOF.
使用Ctrl-Z结束文件的惯例源自CP/M,这是一个非常古老的8080/Z80微型计算机操作系统.它的文件系统没有跟踪文件大小到字节级别,只跟踪到128字节的扇区级别,因此需要另一种方法来标记文件结尾.
微软的DOS尽可能与CP/M兼容,因此它在阅读文本文件时保持了惯例.到目前为止,文件系统保留了文件大小,因此不是必需的,只是为了向后兼容而保留.
这个约定一直持续到今天在Windows的C和C++库中; 当您在文本模式下打开文件时,将检查每个字符的Ctrl-Z,如果检测到,则设置文件结束标志.您已经看到向后兼容性的影响已经达到极致,回到了将近40年的系统.