cin对于bool的意外行为

Unexpected behaviour of cin for bool

本文关键字:意外 对于 bool cin      更新时间:2023-10-16

我试图使用cin在bool类型数组中输入。如果输入像0111100010001000一样,它不会运行所有迭代(在我的输入中是16),它会终止并打印一些垃圾值,但如果输入像0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0一样,它会按预期工作。

#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()可以解决我的问题。

请解释为什么在第一个场景中跳过循环。

operator>>解析bool参数输入的方式在§22.4.2.1.2 [facet.num.get]中指定。[虚拟]/p6的标准:

如果(str.flags()&ios_base::boolalpha)==0,则输入继续将用于long,除非值存储在val中,取值的确定方法如下:如果为存储为0,则存储为false。如果为1,则为true存储。否则存储true,存储ios_base::failbit赋值给err.

因此,如果您给它0111100010001000,它将首先尝试将其解析为long,给您一个大的数字(显然不是1)。然后,处理的第二步将true存储到要设置的boolfailbit中。

cin将空格作为默认分隔符,因此当您从值10101读取时…它认为它只是一个大int。

使用.get()来读取单个字符

for (int i = 0; i < noOfFriends ; i++){
    for (int j = 0; j < noOfFriends; j++){
        mutualFriend[i][j] = (cin.get() == '1');
    }
}
<p已经解释了流式传输到bool的工作方式,概括地说,long被消耗,0> false, 1 -> true,否则true,但failbit设置。

对于一般的数字输入,c++有std::dec用于十进制输入,std::oct用于八进制输入(以8为基数),std::hex用于十六进制输入(以16为基数),但奇怪的是没有用于二进制输入。不能将数字的多位数二进制表示形式直接读入整型。

你要做的是每次读取一个字符,然后自己转换成二进制:

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