1

在 VS 2005 中,我有一些如下所示的代码:

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    loc = ifs.tellg();
    loc += bar.dwHeaderSize;
    // four byte boundary padding
    if ((loc % 4) != 0)
        loc += 4 - (loc % 4);
    ifs.seekg(loc,ios::beg);
}
ifs.close();

该代码在 VS 2005 中运行良好,但在 VS 2008 Express 中失败。据我所知,VS 2008 在代码搜索到文件末尾后没有返回 eof() 。我错过了什么吗?我通过添加显式检查来修复它以查看查找位置是否超过文件大小,但我想确保我正确理解 ifstream。

4

1 回答 1

2

只有在您尝试读取文件末尾之后才会触发 EOF 标志。
读取upto文件末尾不会触发它。

这就是为什么大多数代码看起来像这样:

while(ifs.read(&bar,sizeof(bar)))
{
     // Do Stuff
}

如果 read() 的结果达到 EOF,则将进入循环。
如果 read() 的结果超过了 EOF,则不会进入循环

  • 注意:如果文件中剩下零字节,read() 只会越过 EOF。否则它将读取到文件的末尾。因此,如果文件中还有其他内容,则始终进入循环。

原因是读取的结果(返回值)是对流的引用。如果流在布尔上下文中使用(例如 if 测试表达式),则将其转换为可在此类上下文中使用的类型。此转换的结果测试 EOF 标志(以及其他几个标志),如果 EOF 为真,则返回等效的假。

注意:
如果您为 Bar 类重载运算符 <<,则此技术效果更好,因为它应该准确读取对象所需的内容,而不会超过 EOF。然后更容易使您的对象准确地读取到文件的末尾而无需遍历。我担心 read 的事情是如果 read() 需要 10 个字节并且文件中只有 5 个字节会发生什么,部分填充的对象会发生什么?

如果您想继续使用您的样式,代码应如下所示:

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    if (ifs.eof())
    {    break;
    }
    // Do Stuff
}
于 2009-07-08T18:19:22.860 回答