在 VS 2008 Express 中,ifstreameekg Beyond end 不返回 eof?

发布于 2024-07-27 13:37:07 字数 469 浏览 1 评论 0原文

在 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。

In VS 2005, I have some code that looks like this:

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();

The code worked fine in VS 2005, but it fails in VS 2008 Express. From what I can tell, VS 2008 is not returning eof() after the code seeks to the end of the file. Am I missing something? I fixed it by adding an explicit check to see if the seek location exceeded the file size, but I want to be sure I understand ifstream correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡写薰衣草的香 2024-08-03 13:37:07

仅当您尝试读取文件末尾之后才会触发 EOF 标志。
读取直到文件末尾不会触发它。

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

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

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

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

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

注:
如果您重载运算符 <<,则此技术效果更好。 对于您的 Bar 类,因为这应该准确读取对象所需的内容,而不会超过 EOF。 这样就可以更轻松地让对象准确读取到文件末尾而无需越过。 我对 read 担心的事情是,如果 read() 需要 10 个字节,而文件中只有 5 个字节,那么部分填充的对象会发生什么?

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

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    if (ifs.eof())
    {    break;
    }
    // Do Stuff
}

The EOF flag is only triggered after you attempt to read past the end of file.
Reading upto the end of file will not trigger it.

This is why most code looks like this:

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

If the result of the read() goes upto the EOF the loop will be entered.
If the result of the read() goes past the EOF the loop will NOT be enetered

  • NOTE: read() will only go past the EOF if there are zero bytes left in the file. Otherwise it will read upto the end of the file. So The loop is always entered if there was somthing left in the file.

The reason is the result of the read (the return value) is a reference to the stream. If the stream is used in a boolean context (such as the if test expression) it is converted into a type that can be used in such a context. The result of this conversion tests the EOF flag (in addition to a couple of others) and returns the quivalent of false if EOF is true.

Note:
This techniques works better if you overload the operator << for your Bar class as this should read in exactly what it needs for the object without going past the EOF. It is then easier to make your objects read exactly upto the end of the file without going over. The thing I worry about with read is what should happen if read() wants 10 bytesand there are only 5 bytes in the file, what happens with the partially filled object?

If you want to continue using your style the code should look like this:

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    if (ifs.eof())
    {    break;
    }
    // Do Stuff
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文