if(!cin) and if(cin.fail())

I searched for it on the net and didn't find a straight answer.
Does if(!cin) do exactly the same thing that the if(cin.fail()) does?
Are they completely identical? Is if(!cin) only the shorter way to check the stream state?
Yes, they do exactly the same thing.
http://en.cppreference.com/w/cpp/io/ios_base/iostate (bottom of the page)
As Peter87 said they do the same thing, but for the sake of completeness, sometimes the information returned by them could be not enough.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>

int main()
{
    std::cin.setstate(std::ios::badbit);
    if(!std::cin) {
        std::cout << "\nAfter setstate(badbit) cin is in a bad state.\n";
    }
    if(std::cin.fail()) {
        std::cout << "fail(): I can confirm an error occurred.\n";
    }
    if(std::cin.bad()) {
        std::cout << "bad(): I can confirm a non-recoverable error occurred.\n";
    }
    if(std::cin.eof()) {
        std::cout << "eof(): I can confirm end-of-file has been met.\n";
    }
    std::cout << "std::cin state: " << std::cin.rdstate() << '\n';

    std::cin.clear();

    std::cin.setstate(std::ios::failbit);
    if(!std::cin) {
        std::cout << "\nAfter setstate(failbit) cin is in a bad state.\n";
    }
    if(std::cin.fail()) {
        std::cout << "fail(): I can confirm an error occurred.\n";
    }
    if(std::cin.bad()) {
        std::cout << "bad(): I can confirm a non-recoverable error occurred.\n";
    }
    if(std::cin.eof()) {
        std::cout << "eof(): I can confirm end-of-file has been met.\n";
    }
    std::cout << "std::cin state: " << std::cin.rdstate() << '\n';

    std::cin.clear();

    std::cin.setstate(std::ios::eofbit);
    if(!std::cin) {
        std::cout << "\nAfter setstate(eofbit) cin is in a bad state.\n";
    } else {
        std::cout << "\nAfter setstate(eofbit) cin is still in a good state.\n";
    }
    if(std::cin.fail()) {
        std::cout << "fail(): I can confirm an error occurred.\n";
    }
    if(std::cin.bad()) {
        std::cout << "bad(): I can confirm a non-recoverable error occurred.\n";
    }
    if(std::cin.eof()) {
        std::cout << "eof(): I can confirm end-of-file has been met.\n";
    }
    std::cout << "std::cin state: " << std::cin.rdstate() << '\n';
    return 0;
}


After setstate(badbit) cin is in a bad state.
fail(): I can confirm an error occurred.
bad(): I can confirm a non-recoverable error occurred.
std::cin state: 1

After setstate(failbit) cin is in a bad state.
fail(): I can confirm an error occurred.
std::cin state: 4

After setstate(eofbit) cin is still in a good state.
eof(): I can confirm end-of-file has been met.
std::cin state: 2

Thank you. Sorry for taking your time, two other questions:
1_ What is the logic behind those numbers?(1,4,2) Why might we need to use them?
2_ is std::ios::failbit a static boolean public data member of the class istream?
(boolean because it can be set/unset)
(static because we can access it without using any objects)
Last edited on
What is the logic behind those numbers?(1,4,2)

They are the numeric values of the particular flags with the compiler that was used to compile the code.

Why might we need to use them?

You should never really need to use these numbers and you should never rely on these numbers being the same between different compilers. These numbers are implementation details that could vary between compilers. If you need to interpret the stream state returned by rdstate() use the implementation defined constants instead (eofbit, failbit, badbit, and goodbit).

What is the logic behind those numbers? (1,4,2)

As many flags, they increase by the power of two, to make possible to add (‘or’) them without overlapping other values.
In this case, you could for example use them this way:
std::cin.setstate(std::ios::badbit | std::ios::eofbit);
which would result in a state of 3. Since 3 is not a power of two, there can’t be another flag which has the value 3.
(Anyway, as jlb specified, the standard library doesn’t define them, so every compiler is implemented with its own set of data and paradoxically the developers could have chosen to set some values not as powers of two, which I really can’t believe.)

The usage is the same of the openmode flags
http://en.cppreference.com/w/cpp/io/ios_base/openmode
When you open a file, you can specify its open mode by those flags:
std::ofstream myfile(“mydata.txt”, std::ios_base::app | std::ios_base::binary);

Why might we need to use them?

The standard library offers you some good alternatives, so you usually don’t need to use them. You can use:
if(cin.good()) // fast and comfortable
or
if(std::cin.rdstate() == std::ios::goodbit) // prolix
I was just giving you general examples, not suggesting any strategy.

is std::ios::failbit a static boolean public data member of the class istream?

It’s more likely to be an integer rather than a boolean. The standard library says it is a “BitmaskType”, which:
Defines a type that can be used to represent a set of constant values or any combination of those values. This trait is typically implemented by integer types, std::bitset, or enumerations (scoped and unscoped) with additional operator overloads.

http://en.cppreference.com/w/cpp/concept/BitmaskType

But it’s static, as you said, just read its documentation.
Last edited on
Topic archived. No new replies allowed.