rdstate()返回值意味着什么?

时间:2015-03-15 08:16:13

标签: c++ c++11 io eof

istream& Read(istream &is)
{
    std::string buf;
    while (is >> buf)       
    {   
        cout << is.eofbit << " " << is.failbit << " " << is.badbit << endl;
        cout << is.rdstate() << endl;
        cout << buf << endl;
    }
    cout << is.eofbit << " " << is.failbit << " " << is.badbit << endl;
    cout << is.rdstate() << endl;
    is.clear();
    cout << is.eofbit << " " << is.failbit << " " << is.badbit << endl;
    cout << is.rdstate() << endl;
    return is;
}

如果我输入正常字符,例如&#34; test&#34;,则输出为1 2 4 0 然后我输入CTRL + Z(窗口),输出为1 2 4 3 1 2 4 0

问题: 1. rdstate()返回值的含义是什么? (为什么它输出3,而不是2?不是1?)

  1. 键入CTRL + Z后,为什么is.eofbitis.failbit没有变化? (正如 C ++ Primer 5th Editon 所说,达到文件结尾设置eofbit和failbit)

2 个答案:

答案 0 :(得分:4)

成员std::ios::rdstate()只返回状态标记std::ios_base::badbitstd::ios_base::eofbitstd::ios_base::failbit的组合。在哪些条件下设置的位置不完全一致,但意图如下:

    当流处于真正功能失调的状态时,
  1. std::ios_base::badbit会被设置,并且您[可能]不会从中获取任何信息。例如,如果没有流缓冲区或流上的任何操作引发异常,则设置此标志。
  2. 当输入操作失败时,
  3. std::ios_base::failbit被设置,例如,因为格式化的输入操作有意外的字符。可以通过清除它,忽略几个字符并再次尝试来从此错误中恢复。
  4. 当达到[当前] EOF时,
  5. std::ios_base::eofbit被设置,即,暂时不再提取任何字符。
  6. 现在,在您的情况下,您输入了一个字符串并且读取它是成功的,即没有设置标志。请注意,使用换行符停止读取,即您确实输入了"test\n",并且流提取了这五个字符。当您结束流时,流尝试读取字符串时达到EOF,即设置std::ios_base::eofbit 输入失败并设置std::ios_base::failbit

    如果您只想查看std::ios_base::eofbit设置,您可以使用一个流,该流在流的末尾以一个单词结尾,没有任何后续空格字符。获得此类流的简单方法是使用std::istringstream并从中读取:

    std::istringstream in("test");
    Read(in);
    

    另一个简单的设置是看std::ios_base::badbit设置:你只是创建一个没有流缓冲区的流,例如:

    std::istream in(0);
    Read(in);
    

    请注意,流初始设置std::ios_base::badbit,并在尝试读取字符时设置std::ios_base::failbitclear() std::ios_base::badbit之后仍会设置std::ios_base::failbit

    要设置std::ios_base::eofbit而不设置std::string,您需要阻止它看到非空格字符:std::istringstream in("test test"); Read(in >> std::noskipws); 的输入运算符默认情况下从跳过空格开始然后读取,直到它达到空白或EOF,如果它可以读取至少一个非空白字符则成功。这样做的方法是关闭自动跳过空格,例如:

    std::ios_base::eofbit

    顺便说一句,请注意,我们无法保证std::ios_base::failbitstd::ios_base::badbit或{{1}}的值,除非它们可以用作某种形式的位掩码。

答案 1 :(得分:1)

成员std::ios::rdstate()只返回状态标志std::ios_base::badbitstd::ios_base::eofbitstd::ios_base::failbit的组合。但每个状态标志的大小不是1位,所有三个状态标志的类型都是enum std::_Iosb<int>::_Iostate,它是与机器相关的积分以及std::strm::iostate。在我的机器上,它们占4个字节。

  

但我不明白其输出意味着什么

只有badbit被设置为显式或直接时,s.rdstate()的值为4。 当只有failbit被设置为显式或直接时,s.rdstate()的值为2。 当只有eofbit明确或直接设置时,s.rdstate()的值为1。

当它们的几个部分明确或直接设置时,s.rdstate()的值可以从相应值的总和计算得出,即s.rdstate()的第1位表示{{1}的状态} {},eofbit的第2位表示s.rdstate()的状态,failbit的第3位表示s.rdstate()的状态。

但有趣的是,当badbit被明确或直接设置时,badbit将被设置为响应(不明确或直接)。此时,{{1}的值}不要计算failbit。阅读我的代码并查看输出,你就会理解我的意思。

s.rdstate()

输出结果为:

failbit