【问题标题】:Resetting the State of a Stream重置流的状态
【发布时间】:2012-06-30 02:38:24
【问题描述】:

我有一个问题与 stackoverflow std::cin.clear() fails to restore input stream in a good state 上的这个问题有点相似,但那里提供的答案对我不起作用。

问题是:如何将流的状态再次重置为“良好”?

这是我尝试的代码,但状态永远不会再次设置为良好。我分别使用了两行忽略。

int _tmain(int argc, _TCHAR* argv[])
{
    int result;
    while ( std::cin.good() )
    {
        std::cout << "Choose a number: ";
        std::cin >> result;

        // Check if input is valid
        if (std::cin.bad())
        {
            throw std::runtime_error("IO stream corrupted");
        }
        else if (std::cin.fail())
        {
            std::cerr << "Invalid input: input must be a number." << std::endl;
            std::cin.clear(std::istream::failbit);
            std::cin.ignore();
            std::cin.ignore(INT_MAX,'\n');
            continue;
        }
        else
        {
            std::cout << "You input the number: " << result << std::endl;
        }
    }
    return 0;
}

【问题讨论】:

    标签: c++ state iostream conditional-statements


    【解决方案1】:

    这里的代码

    std::cin.clear(std::istream::failbit);
    

    实际上并没有清除故障位,它failbit替换流的当前状态。

    要清除所有位,只需调用clear()


    标准中的描述有点复杂,是其他功能的结果

    void clear(iostate state = goodbit);

    后置条件: 如果rdbuf()!=0state == rdstate(); 否则rdstate()==(state | ios_base::badbit)

    这基本上意味着对rdstate() 的下一次调用将返回传递给clear() 的值。除非有其他问题,在这种情况下,您也可能会收到 badbit

    另外,goodbit 实际上根本不是一个位,而是具有零值以清除所有其他位。

    要清除只是一个特定的位,你可以使用这个调用

    cin.clear(cin.rdstate() & ~ios::failbit);
    

    但是,如果您清除一个标志并保留其他标志,您仍然无法从流中读取。所以这种用途是相当有限的。

    【讨论】:

    • 在我的书中说:clear(flag) 将指定的条件状态设置为有效。我将其解释为:清除指定的错误位。那么这不正确吗?
    • 只需clear() 即可清除所有标志。清除单个标志有点复杂(而且不太有用)。我在答案中添加了一个新部分。
    猜你喜欢
    • 2013-12-11
    • 1970-01-01
    • 2012-04-18
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多