可以在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);
不幸的是,即使我确定文件内容在EOF之后仍然存在,我无法阅读其余内容 .
已解决:使用“rb”而不是“r”进行读取并使用x作为int允许我读取整个文件,包括多个EOF . 不确定这是一个技巧还是允许的东西,但是有效 .
3 回答
Chapter and verse:
EOF
isn 't a character in the file itself; it'是输入函数返回的值,表示流上没有可用的输入;你可以't read past it, because there'什么都不读 .从逻辑上讲,EOF之后没有数据(文件结束) .
请注意
EOF
不是字符;它是getc()
在遇到文件结束或错误条件后返回的特殊值,返回的值而不是字符值 .你在问题中没有这么说,但我的猜测是你有一个带有一个或多个嵌入式Ctrl-Z(
0x1a
)字符的Windows文本文件 . 那's the only thing I can think of that'与你的描述一致 .在Windows中,文本文件中的Ctrl-Z字符被视为文件的末尾 . (这可以追溯到早期的系统,其中数据的末尾没有清楚标记,因为文件系统只记录了块的数量 . )Ctrl-Z不是EOF字符;它是一个字符值,在Windows上,触发和文件结束条件,并导致
getc()
返回EOF
.基本上你有一个格式错误的文本文件,你应该只修复它和/或修复生成它的任何内容 . 但是如果你真的需要从中读取数据,我建议以二进制模式而不是文本模式打开它 . 然后,您将看到每个CR / LF行结束标记为两个字符(
'\r'
,'\n'
而不仅仅是'\n'
),而Ctrl-Z(0x1a
)只是另一个字节值 . 由于您并未真正将文件视为文本("text"在第一个Ctrl-Z处结束),因此以二进制模式读取它是有意义的 .在文本模式下,您可以通过Ctrl-Z读取可能的技巧;例如
clearerr()
可能会起作用 . 但这样做超出了C标准所保证的范围 - 这对您来说可能是也可能不是问题 .此外,你绝对应该使用符号
EOF
,而不是"magic number"-1
. 它甚至不能保证EOF == -1
,并使用符号EOF
将使您的代码更清晰 .最后,感谢Mark Plotnick在评论中指出我应该注意到的事情 .
getc()
返回int
结果;你将它分配给char
对象 .x
需要是int
类型,而不是char
. 这是必要的,因此您可以区分EOF
的值和任何实际字符的值 .你的代码不完整,所以很难说出问题所在,但我建议:
确保以二进制模式打开文件"rb"
确保
x
的类型为int