【问题标题】:std::ws behavior on EOFEOF 上的 std::ws 行为
【发布时间】:2020-08-07 10:09:43
【问题描述】:

我偶然发现了不同编译器之间的行为差​​异。假设如下代码:

#include <sstream>
#include <iostream>

using namespace std;

int main() {
    istringstream ss("100");
    int val;
    ss >> val;
    cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
    ss >> std::ws;
    cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
}

VS2019 和 Clang 10 使用 libc++ 生成的输出是:

fail: 0 eof: 1
fail: 1 eof: 1

而带有 libstdc++ 的 VS2015 和 GCC 10.2 生成:

fail: 0 eof: 1
fail: 0 eof: 1

所以问题是哪个实现是正确的? std::ws应该在eofbit已经设置的情况下设置failbit吗?

我在标准中查找了std::ws,上面写着:

30.7.4.4 标准 basic_istream 操纵器 [istream.manip]

模板 basic_istream& ws(basic_istream& is);

效果:表现为未格式化的输入函数 (30.7.4.3),除了 它不计算提取的字符数,也不计算 影响后续调用 is.gcount() 返回的值。后 构造一个哨兵对象提取字符只要下一个 可用字符 c 是空格或直到没有更多 序列中的字符。区分空白字符 使用与 sentry::sentry (30.7.4.1.3) 相同的标准。如果 ws 停止提取字符,因为没有更多可用的字符 设置 eofbit,但不设置 failbit。

所以最后明确声明它设置 eofbit,但当没有可用字符时不设置 failbit。但它也表现为一个未格式化的输入函数,它创建一个sentry 对象。当is.good() 为假时,sentry 构造函数将调用is.setstate(failbit)。所以在某种程度上,两种实现都不是完全错误的。更了解标准的人能否澄清哪种行为是正确的以及我应该在哪里提交错误?

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    failbit 应该被设置。它是由sentry 对象完成的,ws 首先构造什么。

    [istream::sentry]/2
    explicit sentry(basic_istream&lt;charT, traits&gt;&amp; is, bool noskipws = false);
    效果:如果 is.good() 是 false,则调用 is.setstate(failbit)。否则,...

    【讨论】:

    猜你喜欢
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多