what does rdstate() return value means?

后端 未结 2 632
忘掉有多难
忘掉有多难 2021-02-09 19:12
istream& Read(istream &is)
{
    std::string buf;
    while (is >> buf)       
    {   
        cout << is.eofbit << \" \" << is.failbit          


        
相关标签:
2条回答
  • 2021-02-09 19:49

    The member std::ios::rdstate() simply returns a combination of the state flags std::ios_base::badbit, std::ios_base::eofbit, and std::ios_base::failbit. Under which conditions which bits gets set isn't entirely consistent but the intent is the following:

    1. std::ios_base::badbit gets set when the stream is in genuinely dysfunctional state and you [probably] won't get anything out of it. For example, this flag is set if there is no stream buffer or when any of the operations on the stream has thrown an exception.
    2. std::ios_base::failbit gets set when an input operation failed, e.g., because a formatted input operation got an unexpected characters. It may be possible to recover from this error by clearing it, ignoring a few characters, and trying again.
    3. std::ios_base::eofbit gets set when [the current] EOF is reached, i.e., when there could be no more characters extracted for now.

    Now, in your case you entered a string and reading it was successful, i.e., there are no flags set. Note that reading stopped with the newline character, i.e., you really entered "test\n" and the stream extracted these five characters. When you then ended the stream, the stream reached EOF while trying to read a string, i.e., it set std::ios_base::eofbit and the input failed also setting std::ios_base::failbit.

    If you want to see only std::ios_base::eofbit set, you can do so by using a stream which ends with a word right at the end of the stream without any following space character. An easy way to get such a stream is to use an std::istringstream and read from that:

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

    Another easy set up is to see std::ios_base::badbit set: you'd just create a stream without a stream buffer, e.g.:

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

    Note that the stream will initially have std::ios_base::badbit set and also get std::ios_base::failbit set upon an attempt to read a character. After clear()ing the std::ios_base::badbit will still be set, though.

    To get std::ios_base::failbit set without also having std::ios_base::eofbit set you'll need to prevent it from seeing a non-whitespace character: the input operator for std::string by default start off skipping whitespace and then reads until it either reaches whitespace or EOF and it is successful if it could read at least one non-whitespace character. An approach to do that is to turn automatic skipping of whitespace off, e.g.:

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

    BTW, note that there is no guarantee for the values of std::ios_base::eofbit, std::ios_base::failbit, or std::ios_base::badbit other than they can be used as bitmasks in some form.

    0 讨论(0)
  • 2021-02-09 20:07

    The member std::ios::rdstate() simply returns a combination of the state flags std::ios_base::badbit, std::ios_base::eofbit, and std::ios_base::failbit.But the size of each state flag is not 1 bit, the type of all three state flags are enum std::_Iosb<int>::_Iostate, which is machine-dependent integral as well as std::strm::iostate. On my machine, they account for 4 bytes.

    But I don't understand what its output means

    when only badbit gets set explicity or directly, the value of s.rdstate()is 4. when only failbit gets set explicity or directly, the value of s.rdstate() is 2. when only eofbit gets set explicity or directly, the value of s.rdstate() is 1.

    when several parts of them get set explicity or directly, the value of s.rdstate() can calculated from the sum of the corresponding value, namely, the 1st bit of s.rdstate()indicates the state ofeofbit,the 2nd bit of s.rdstate()indicates the state offailbit,the 3th bit of s.rdstate()indicates the state ofbadbit.

    But the interesting thing is when the badbit gets set explicitly or directly, the failbit will get set in response(not explicity or directly).At this time, the value of s.rdstate() do not count failbit in. Read my code and see the output, you will understand what I mean.

    #include<iostream>
    #include<istream>
    
    std::istream & print(std::istream &is) {
        static unsigned cnt = 0;
        ++cnt;
        std::cout << cnt << ((cnt % 10 == 1) ? "st" :
            (cnt % 10 == 2) ? "nd" : "th")
            << " call print" << "\n";
    
        std::cout<< "is.badbit: " << is.badbit << "\n"
            << "is.failbit: " << is.failbit << "\n"
            << "is.eofbit: " << is.eofbit << "\n"
            << "is.bad(): " << is.bad() << "\n" 
            << "is.fail(): " << is.fail() << "\n"
            << "is.eof(): " << is.eof() << "\n"
            << "is.rdstate(): " << is.rdstate() << "\n";
        return is;
    }
    
    using std::cin;
    using std::cout;
    using std::endl;
    using std::vector;
    
    int main()
    {
        cout << "sizeof(iostate): " <<sizeof(std::istream::iostate)<<"\n";
        cout << "sizeof(goodbit): " << sizeof(std::istream::goodbit) << "\n";
        cout << typeid(std::istream::goodbit).name();
        cout << endl;
    
        print(cin);
        cout << endl;
    
        cin.setstate(std::istream:: badbit);
        print(cin);
        cout << endl;
    
        cin.clear();
        cin.setstate(std::istream::failbit);
        print(cin);
        cout << endl;
    
        cin.clear();
        cin.setstate(std::istream::eofbit);
        print(cin);
        cout << endl;
    
    
        cin.clear();
        cin.setstate(std::istream::badbit);
        cin.setstate(std::istream::failbit);
        print(cin);
        cout << endl;
    
        cin.clear();
        cin.setstate(std::istream::badbit);
        cin.setstate(std::istream::eofbit);
        print(cin);
        cout << endl;
    
        cin.clear();
        cin.setstate(std::istream::failbit);
        cin.setstate(std::istream::eofbit);
        print(cin);
        cout << endl;
    }
    

    The output is:

    sizeof(iostate): 4
    sizeof(goodbit): 4
    
    1st call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 0
    is.fail(): 0
    is.eof(): 0
    is.rdstate(): 0
    
    2nd call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 1
    is.fail(): 1
    is.eof(): 0
    is.rdstate(): 4
    
    3th call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 0
    is.fail(): 1
    is.eof(): 0
    is.rdstate(): 2
    
    4th call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 0
    is.fail(): 0
    is.eof(): 1
    is.rdstate(): 1
    
    5th call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 1
    is.fail(): 1
    is.eof(): 0
    is.rdstate(): 6
    
    6th call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 1
    is.fail(): 1
    is.eof(): 1
    is.rdstate(): 5
    
    7th call print
    is.badbit: 4
    is.failbit: 2
    is.eofbit: 1
    is.bad(): 0
    is.fail(): 1
    is.eof(): 1
    is.rdstate(): 3
    
    0 讨论(0)
提交回复
热议问题