EOF后读取文件

时间:2016-06-30 16:05:45

标签: c

可以在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 个答案:

答案 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)

您的代码不完整,因此很难说出问题所在,但我建议:

  1. 确保以二进制模式打开文件&#34; rb&#34;
  2. 确保x的类型为int

答案 2 :(得分:0)

Chapter and verse

7.21输入/输出&lt; stdio.h&gt;

7.21.1简介

...
3宏是......

EOF

它扩展为整数常量表达式,类型为int,负值为 由几个函数返回以指示文件结尾,即不再有来自a的输入 流;

EOF不是文件本身的字符;它是输入函数返回的值,表示流上没有可用的输入;你无法阅读它,因为没有什么可读的。