CaTx
CaTx

Reputation: 1481

cin.clear(ios_base::failbit) vs cin.setstate(ios_base::failbit)

For one of my assignments, I was told to use cin.clear(ios_base::failbit) to set the failbit. I wonder, what is the difference between cin.clear(ios_base::failbit) and cin.setstate(ios_base::failbit)? Is the latter not clearer? I am a bit surprised to see how the failbit is set with clear(). Why such a counter-intuitive way for using clear()?

Upvotes: 4

Views: 2379

Answers (2)

Rick
Rick

Reputation: 7506

setstate and clear do different operations. They are not the same.

setstate actually calls clear with extra operation.

Basically, setstate is somehow adding extra flag while clear is to override the whole thing.

See here:http://www.cplusplus.com/reference/ios/ios/setstate/

Modifies the current internal error state flags by combining the current flags with those in argument state (as if performing a bitwise OR operation). ...
This function behaves as if defined as:

void ios::setstate (iostate state) {
  clear(rdstate()|state);   //setstate is doing a OR operation while clear does not.
}

or here:http://en.cppreference.com/w/cpp/io/basic_ios/setstate

Sets the stream error flags state in addition to currently set flags. Essentially calls clear(rdstate() | state).

Experiment code for VC++:

First find out how are the iostate constant implemented:

//Windows Visual C++ implementation
static constexpr _Iostate goodbit = (_Iostate)0x0;
static constexpr _Iostate eofbit = (_Iostate)0x1;
static constexpr _Iostate failbit = (_Iostate)0x2;
static constexpr _Iostate badbit = (_Iostate)0x4;

Then:

#include <iostream>
#include <sstream>
using namespace std;
int main()
{
    //eof 1, fail 2.
    std::ostringstream stream;
    stream.setstate(std::ios_base::failbit);
    cout << stream.rdstate() << endl;  // should get 2
    stream.setstate(ios_base::eofbit);
    cout << stream.rdstate() << endl; // should get 3
    stream.clear(ios_base::eofbit);
    cout << stream.rdstate() << endl; // should get 1

}

Upvotes: 3

Justin Randall
Justin Randall

Reputation: 2278

I am a bit surprised to see how the fail bit is set with clear(). Why such a counter-intuitive way for using clear()?

Well let's think about it.

 std::cin.setstate(ios_base::failbit);

This will set the fail bit if it isn't already set, but preserve any other stream error state for std::cin.

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

This will clear all the stream error state from std::cin and then set only the fail bit.

Upvotes: 5

Related Questions