可以在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。不确定这是一个技巧还是允许的东西,但是有效。
答案 0 :(得分:5)
逻辑上,EOF之后没有数据(文件结束)。
请注意EOF
不是字符;它是getc()
在遇到文件结束或错误条件后返回的特殊值,返回而不是字符值。
你在问题中没有说过,但我的猜测是你有一个带有一个或多个嵌入式Ctrl-Z(0x1a
)字符的Windows文本文件。这是我唯一能想到的与你的描述一致的事情。
在Windows中,文本文件中的Ctrl-Z字符被视为文件的末尾。 (这可以追溯到早期的系统,其中数据的末尾没有清楚标记,因为文件系统只记录了块的数量。)Ctrl-Z不是EOF字符;它是一个字符值,在Windows上触发和文件结束条件并导致getc()
返回EOF
。
基本上你有一个格式错误的文本文件,你应该只修复它和/或修复生成它的任何内容。但是如果你真的需要从中读取数据,我建议以二进制模式而不是文本模式打开它。然后,您会将每个CR / LF行尾标记看作两个字符('\r'
,'\n'
而不仅仅是'\n'
)和Ctrl-Z({{1 }})只是另一个字节值。由于您并未真正将文件视为文本(&#34;文本&#34;在第一个Ctrl-Z处结束),因此以二进制模式读取文件是有意义的。
在文本模式下,您可以通过Ctrl-Z读取可能的技巧;例如0x1a
可能会起作用。但这样做超出了C标准所保证的范围 - 这对您来说可能是也可能不是问题。
此外,你绝对应该使用符号clearerr()
,而不是&#34;幻数&#34; EOF
。它甚至不能保证-1
,并且使用符号EOF == -1
会使您的代码更清晰。
最后,感谢Mark Plotnick在评论中指出我应该注意到的事情。 EOF
会返回getc()
个结果;您将其分配给int
对象。 char
必须是x
类型,而不是int
。这是必要的,因此您可以区分char
的值和任何实际字符的值。
答案 1 :(得分:0)
您的代码不完整,因此很难说出问题所在,但我建议:
x
的类型为int
答案 2 :(得分:0)
7.21输入/输出&lt; stdio.h&gt;
7.21.1简介
...
3宏是......
的 EOF 强>
它扩展为整数常量表达式,类型为int
,负值为 由几个函数返回以指示文件结尾,即不再有来自a的输入 流;
EOF
不是文件本身的字符;它是输入函数返回的值,表示流上没有可用的输入;你无法阅读它,因为没有什么可读的。