我在Windows上编程C(系统语言是日语),我有关于二进制文件和ascii文件的EOF的问题。
我上周问了this question,一个善良的人帮了我,但是我仍然无法理解程序在阅读二进制文件或ascii文件时的工作原理。
我做了以下测试:
测试1:
int oneChar;
iFile = fopen("myFile.tar.gz", "rb");
while ((oneChar = fgetc(iFile)) != EOF) {
printf("%d ", oneChar);
}
的Test2:
int oneChar;
iFile = fopen("myFile.tar.gz", "r");
while ((oneChar = fgetc(iFile)) != EOF) {
printf("%d ", oneChar);
}
在test1的情况下,对二进制文件和ascii文件都有效。但是在test2中,程序在二进制文件中遇到 0x1A 时停止读取。 (这是否意味着 1A == EOF ?)ASCII表告诉我1A是一个名为替换的控制字符(无论这意味着什么......)当我printf( "%d",EOF),然而,它给了我 -1 ......
我还发现this question告诉我操作系统确切知道文件的结束位置,因此我不需要在文件中找到EOF,因为EOF超出了一个字节的范围(1A怎么样?)
有人可以为我清理一下吗?提前谢谢。
答案 0 :(得分:7)
这是特定于Windows的文本文件技巧:SUB
字符,由 Ctrl + Z 序列表示,解释< / {>由EOF
作为fgetc
。您不必在文本文件中包含1A
,以便从EOF
返回fgetc
,但是:一旦到达文件的实际结尾,EOF
就会被退回。
标准未将1A
定义为char
值来表示EOF
。 EOF
的常量属于int
类型,负值超出unsigned char
的范围。事实上,fgetc
返回int
而不是char
的原因是让它返回EOF
的特殊值。
答案 1 :(得分:5)
使用Ctrl-Z结束文件的惯例源自CP / M,这是一个非常古老的8080 / Z80微型计算机操作系统。它的文件系统没有跟踪文件大小到字节级别,只跟踪到128字节的扇区级别,因此需要另一种方法来标记文件结尾。
微软的DOS尽可能与CP / M兼容,因此它在阅读文本文件时保持了惯例。到目前为止,文件系统保留了文件大小,因此不是必需的,只是为了向后兼容而保留。
此约定一直持续到Windows的C和C ++库中;当您在文本模式下打开文件时,将检查每个字符的Ctrl-Z,如果检测到,则设置文件结束标志。你会看到向后兼容性对极端的影响,回到近40年的系统。
答案 2 :(得分:0)
发现了一篇很棒的文章,回答了所有问题! https://latedev.wordpress.com/2012/12/04/all-about-eof/
答案 3 :(得分:0)
EOF通常为字符0x1A 或 ASCII 26 。