princethewinner
princethewinner

Reputation: 61

Unexpected behaviour of cin for bool

I am trying to take input in bool type array using cin. If input is given like 0111100010001000 it instead of running for all iteration ( In my input it is 16 ) it terminates and print some garbage values, But if input is given like 0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 it works as expected.

#include<cstdio>
#include<cstring>
#include<iostream>

#define FRND 2001

using namespace std;

int main(){
    bool mutualFriend[FRND][FRND];
    int noOfFriends = 0;
    cin >> noOfFriends;
    for (int i = 0; i < noOfFriends ; i++){
        for (int j = 0; j < noOfFriends; j++){
            cin >> mutualFriend[i][j];
        }
    }
    for (int i = 0; i < noOfFriends ; i++){
        for (int j = 0; j < noOfFriends; j++){
            cout << mutualFriend[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

cin.clear() can solve my problem.

Please explain why loops are skipped in the first scenario.

Upvotes: 1

Views: 236

Answers (3)

Tony Delroy
Tony Delroy

Reputation: 106116

T.C. has explained the way streaming in to a bool works, summarily a long is consumed, 0 -> false, 1 -> true, otherwise true but with failbit set.

For general numeric input, C++ has std::dec for decimal input, std::oct for octal (base 8), std::hex for hexadecimal (base 16), but strangely nothing for binary. It is not possible to read a multi-digit binary representation of a number directly into an integral type.

What you'll have to do is read a character at a time, then convert to binary yourself:

`char c;`

...

    if (cin >> c && (c == '0' || c == '1'))
        mutualFriend[i][j] == c != '0';
    else
        throw std::runtime_error("failure to parse binary digit from stream");

Upvotes: 1

AndersK
AndersK

Reputation: 36082

cin has space as default delimiter so when you do read from the value 10101.. it regards it as just a big int.

Instead use .get() to read a single character

for (int i = 0; i < noOfFriends ; i++){
    for (int j = 0; j < noOfFriends; j++){
        mutualFriend[i][j] = (cin.get() == '1');
    }
}

Upvotes: 1

T.C.
T.C.

Reputation: 137315

The way operator>> parses input for a bool argument is specified in §22.4.2.1.2 [facet.num.get.virtuals]/p6 of the standard:

If (str.flags()&ios_base::boolalpha)==0 then input proceeds as it would for a long except that if a value is being stored into val, the value is determined according to the following: If the value to be stored is 0 then false is stored. If the value is 1 then true is stored. Otherwise true is stored and ios_base::failbit is assigned to err.

Therefore, if you give it 0111100010001000 it will first try to parse it as a long, giving you a large number (that obvious isn't 1). Then the second step of the processing causes true to be stored into the bool and failbit to be set.

Upvotes: 3

Related Questions