简体   繁体   English

当达到流的EOF时,seekg()不会设置eofbit。 是设计使然吗?

[英]seekg() does not set eofbit when reaching EOF of a stream. Is it by design?

EDIT: there was a subtle error in my original test program code: the " char=" << aStream.peek() line (and probably the " input pos=" << aStream.tellg() , as well) modified the stream state-flags, so not the real state was reported. 编辑:我的原始测试程序代码中有一个微妙的错误: " char=" << aStream.peek()行(也可能是" input pos=" << aStream.tellg() )修改了流状态标志,因此未报告真实状态。 So those calls must be completely deleted from the code, otherwise we cannot see the real effect of seekg() on the state-flags. 因此,必须从代码中完全删除这些调用,否则我们将看不到seekg()对状态标志的实际影响。 However the result is still the same: the eofbit is not set. 但是结果仍然相同:未设置eofbit

Original post: 原始帖子:

I try to detect EOF of an std::istream by advancing the input pointer with 1 step by calling 我尝试通过调用将输入指针前进1步来检测std::istream的EOF

seekg( 1, std::ios_base::cur )

However seekg() moves 1 position beyond EOF, when it sets the failbit of the stream. 然而seekg()移动超出EOF 1点的位置,当它设置failbit流的。 The eofbit is never set. 永远不会设置eofbit See the output of this test program: 查看此测试程序的输出:

#include <iostream>
#include <sstream>

using namespace std;

void info( int aRelativePos, istream& aStream )
{
    cout << "POS=" << aRelativePos <<
            " input pos=" << aStream.tellg() <<
            " char=" << aStream.peek() <<
            "\tGood: " << aStream.good() <<
            " Eof: " << aStream.eof() <<
            " Bad: " << aStream.bad() <<
            " Fail: " << aStream.fail() << "\n";
}

int main()
{
    istringstream   input ("12");

    int i=0;
    while ( input.good() )
    {
        info( i, input );
        input.seekg( 1, std::ios_base::cur ); //advance 1 step forward
        ++i;
    }
    info ( i, input );

    return 0;
}

Output: 输出:

POS=0 input pos=0 char=49   Good: 1 Eof: 0 Bad: 0 Fail: 0
POS=1 input pos=1 char=50   Good: 1 Eof: 0 Bad: 0 Fail: 0
POS=2 input pos=-1 char=-1  Good: 1 Eof: 0 Bad: 0 Fail: 0
POS=3 input pos=-1 char=-1  Good: 0 Eof: 0 Bad: 0 Fail: 1

(Compiled by gcc 5.2 with -std=c++11 . You can run this code here: http://coliru.stacked-crooked.com/a/69f4d70e93359423 ) (由带有-std=c++11的gcc 5.2编译。您可以在此处运行以下代码: http : //coliru.stacked-crooked.com/a/69f4d70e93359423

Moreover MS document on seekg ( https://msdn.microsoft.com/en-us/library/y2d6fx99(v=vs.120).aspx ) says that relative positioning in text files is not supported by the C++ Standard. 此外,关于seekg MS文档( https://msdn.microsoft.com/zh-cn/library/y2d6fx99(v=vs.120).aspx )指出,C ++标准不支持文本文件中的相对定位。

But I could not find such info in the Standard. 但是我在标准中找不到这样的信息。 Can you please give me the reference? 你能给我参考吗?

Well as long as you are okay with the standard says this is the behavior we have from [istream.unformatted] 只要您对标准表示满意,这就是我们从[istream.unformatted]获得的行为

basic_istream<charT,traits>& seekg(pos_type pos);

Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), except that the function first clears eofbit , it does not count the number of characters extracted, and it does not affect the value returned by subsequent calls to gcount() . 效果:表现为未格式化的输入函数(如27.7.2.3,第1段中所述),不同之处在于该函数首先清除eofbit ,它不计算提取的字符数,并且不影响后续对的调用返回的值。 gcount() After constructing a sentry object, if fail() != true , executes rdbuf()->pubseekpos(pos, ios_base::in) . 构造哨兵对象后,如果fail() != true ,则执行rdbuf()->pubseekpos(pos, ios_base::in) In case of failure, the function calls setstate(failbit) (which may throw ios_base::failure ). 如果发生故障,该函数将调用setstate(failbit) (可能会引发ios_base::failure )。

So per the standard we will always clear the eofbit and on an failure only the fail bit is set. 因此,按照标准,我们将始终清除eofbit并且在发生故障时仅设置故障位。 Trying to read past the end of failure is a failure so that is why it gets set. 尝试读取失败结束之后就是失败,所以这就是为什么要设置它。 Just reaching the end of file is not a failure as the end is a valid position. 仅到达文件末尾并不是失败,因为末尾是有效位置。

You can see in this example(modified from your code) that once we reach the end of file we are still good and then trying to read from there will not only set the eofbit but also the failbit as we are at the end of file and the extraction fails 您可以在此示例中(从您的代码修改而来)看到,一旦我们到达文件末尾,我们仍然会很好,然后尝试从那里读取不仅会设置eofbit ,还会设置eofbit failbit就像我们在文件末尾一样。提取失败

input.seekg(0, std::ios::end);
info (input);
char ch;
input >> ch;
info (input);

Output: 输出:

Good: 1 Eof: 0 Bad: 0 Fail: 0
Good: 0 Eof: 1 Bad: 0 Fail: 1

Live Example 现场例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM