可以在EOF之后读取文件吗?
我正在读取一个文件,该文件在其结尾或多个EOF字符之前可能包含EOF字符.该文件是一个简单的文本,我能够知道使用fsize的字符数,但看起来像getc从EOF返回到文件末尾的EOF(或-1).
int c = 0;
char x;
FILE *file = fopen("MyTextFile.txt", "r");
off_t size = fsize("MyTextFile.txt");
while (c < size) {
x = getc(file);
if (x != -1)
printf("%c ", x);
else
printf("\nFOUND EOF!\n");
c++;
}
fclose(file);
Run Code Online (Sandbox Code Playgroud)
不幸的是,即使我确定文件内容在EOF之后仍然存在,我无法阅读其余内容.
已解决:使用"rb"而不是"r"进行读取并使用x作为int允许我读取整个文件,包括多个EOF.不确定这是一个技巧还是允许的东西,但是有效.
从逻辑上讲,EOF之后没有数据(文件结束).
请注意,这EOF不是一个角色; 它是getc()在遇到文件结束或错误条件后返回的特殊值,返回的值而不是字符值.
你在问题中没有这么说,但我的猜测是你有一个带有一个或多个嵌入式Ctrl-Z(0x1a)字符的Windows文本文件.这是我唯一能想到的与你的描述一致的东西.
在Windows中,文本文件中的Ctrl-Z字符被视为文件的末尾.(这可以追溯到早期的系统,其中数据的末尾没有清楚标记,因为文件系统只记录了块的数量.)Ctrl-Z不是EOF字符; 它是一个字符值,在Windows上,触发和文件结束条件并导致getc()返回EOF.
基本上你有一个格式错误的文本文件,你应该只修复它和/或修复生成它的任何内容.但是如果你真的需要从中读取数据,我建议以二进制模式而不是文本模式打开它.然后你会看到每个端部的行CR/LF标记为两个字符('\r','\n'而不仅仅是'\n'),和Ctrl-Z( 0x1a)是另一种字节值.由于您并未真正将文件视为文本("文本"在第一个Ctrl-Z处结束),因此以二进制模式读取它是有意义的.
在文本模式下,您可以通过Ctrl-Z读取可能的技巧; 例如clearerr(),可能会奏效.但这样做超出了C标准所保证的范围 - 这对您来说可能是也可能不是问题.
此外,你绝对应该使用符号EOF,而不是 "幻数" -1.它甚至不能保证EOF == -1,并且使用符号EOF将使您的代码更清晰.
最后,感谢Mark Plotnick在评论中指出我应该注意到的事情.getc()返回int结果; 你将它分配给一个char对象.x需要是类型int,而不是char.这是必要的,因此您可以区分EOF任何实际字符的值和值.