简体   繁体   中英

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.

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.

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

TC 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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM