Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what does rdstate() return value means?

Tags:

c++

io

c++11

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;
}

If I input normal characters like "test",the output is 1 2 4 0.
Then I type CTRL+Z (windows),the output is 1 2 4 3 1 2 4 0.

Question : 1. what does rdstate() return value means? (Why does it output 3,not 2? not 1?)

  1. Why did not is.eofbitand is.failbit change after I typed CTRL+Z ? (As C++ Primer 5th Editon says,Reaching end-of-file sets both eofbit and failbit )
like image 714
Ocxs Avatar asked Mar 15 '15 08:03

Ocxs


People also ask

What is rdstate() method of iOS class in C++?

The rdstate () method of ios class in C++ is used to read the internal state of this stream. Parameters: This method does not accept any parameter. Return Value: This method returns the current internal state of this stream.

What is the use of return statement in a function?

This syntax is used in function just as a jump statement in order to break the flow of the function and jump out of it. One can think of it as an alternative to “ break statement ” to use in functions. But if the return statement tries to return a value in a void return type function, that will lead to errors.

What happens when you return a value from a function?

As soon as the statement is executed, the flow of the program stops immediately and return the control from where it was called. The return statement may or may not return anything for a void function, but for a non-void function, a return value is must be returned. Take a step-up from those "Hello World" programs.

What are the different types of return statements?

Return statements come in many shapes. The following syntaxes are most common: in C and C++, undefined behavior if function is value-returning In some assembly languages, for example that for the MOS Technology 6502, the mnemonic "RTS" (ReTurn from Subroutine) is used.


2 Answers

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.

like image 166
Dietmar Kühl Avatar answered Oct 20 '22 14:10

Dietmar Kühl


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
like image 43
K.Robert Avatar answered Oct 20 '22 15:10

K.Robert