免责声明:不要使用::feof()
作为你的循环条件。例如,看到答案:file reading: feof() for binary files为什么:: feof()与:: _ eof(:: fileno())不同?
不过,我有“真实”的代码,演示了不使用::feof()
作为我的循环条件的问题,但在逻辑上,这是为了说明问题的最简单的方法。
考虑以下情况:我们遍历一个字符流一在-A-时间:
FILE* my_file;
// ...open "my_file" for reading...
int c;
while(0 == ::feof(my_file))
{ // We are not at EOF
c = ::getc(my_file);
// ...process "c"
}
上面的代码按预期工作:文件处理单字符-AT-A-时间,并在EOF
,我们退出。
然而,下面有意外的行为:
FILE* my_file;
// ...open "my_file" for reading...
int c;
while(0 == ::_eof(::fileno(my_file)))
{ // We are not at EOF
c = ::getc(my_file);
// ...process "c"
}
我本来期望他们执行相同。 ::fileno()
每次都正确地返回(整数)文件描述符。然而,测试::_eof(::fileno(my_file))
工作恰好一次,然后在第二次尝试返回1
(指示EOF
)。
我不明白这一点。
我想可以设想::feof()
是“缓冲”(所以它工作正常),而::_eof()
是“未缓冲”,并认为整个文件已被“读入”(因为整个文件将适合从磁盘读入的第一个块)。但是,鉴于这些功能的目的,这不可能是真实的。所以,我真的很茫然。
发生了什么事?
(文件被打开的 “文字”,是ASCII文本文件与大约十几行,MSVS2008中,Win7/64)。
您应该检查getc()的返回值以检查EOF。 if(c!= EOF)http://www.cplusplus.com/reference/clibrary/cstdio/getc/ – 2012-01-09 03:13:35
您的代码仍然不正确。您必须在*阅读后检查EOF *,但在*处理之前检查。直到遇到它,才会看到文件结尾。 – 2012-01-09 03:14:06
同意上面的两条评论(@Rajendran && @Kerrek)。但是,这些问题在我的用例中不存在:文件不是空的,并且有多行; 'feof()'正常工作; '_eof(fileno())'在第一个字符被读取后失败(返回'1')。所以,关于我的“不正确的情况”的合理投诉不适用于这种情况。 (这就是为什么我带着一个免责声明来领导。) – charley 2012-01-09 03:26:42