while循环未提示用户输入(C++)

4
我的循环运行良好,直到我输入性别的最后一个值为“true”时,循环会忽略剩余循环的cin,并只打印cout中的文本,直到循环结束,有什么办法让循环在每次循环时都要求输入或者我在哪里犯了错误? PS:这是一项学校作业,所以我无法更改给定的结构。感谢任何建议。代码片段如下:
int main()
{
    struct Patient
    {
        double height;
        double weight;
        int age;
        bool isMale;
    };
    Patient ListOfPatients[4];
    int iii = 0;

    while (iii < 4)
    {
        cout << "enter the height (eg. 1.80 metres) of patient number  " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].height;
        cout << "enter the weight (eg. 80kg) of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].weight;
        cout << "enter the age of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].age;
        cout << "is the patient a male? (true = male or false = female) " << endl;
        cin >> ListOfPatients[iii].isMale;

        iii++;
    }

    return 0;
}

2
这将允许您输入“true/false”。https://en.cppreference.com/w/cpp/io/manip/boolalpha - 001
4个回答

4
问题出现在读取isMale时。一个bool其实是一个数字,false对应0true对应1。你无法将一个字符串读入其中。
问题在于你最终会得到一串字符,这些字符无法被任何>>操作读取,因此它们都会依次失败。尝试在命令行中传递10,就可以正常工作了。
如果你想让用户能够传递一个字符串,然后将其视为一个bool,你可以使用专门提供的实用程序,或者手动处理以帮助你理解。
要使用标准实用程序,它被称为std::boolalpha,并位于<iomanip>头文件中:
std::cin >> std::boolalpha >> ListOfPatients[i].isMale;

如果要手动完成此操作,需要将其读入一个std::string对象中并进行一些比较,如下所示:

std::string tmpIsMale;
std::cin >> tmpIsMale;
ListOfPatients[i].isMale = (tmpIsMale == "true");

出于这个原因,检查流的状态是否已读取也是一个好主意。您可以将流直接放入if中进行检查:

std::cin >> someVariable;
if (!cin) { // cin is not in a good state
    std::cerr << "Failed to read someVariable, please try again with a proper value!\n";
    return 1;
}

以下是一些需要避免的附加和不良做法:

  1. using namespace std; 被广泛认为是不良实践。
  2. std::endl 存在争议,但你使用方式表明你不理解它。
  3. 性别不是布尔选项。我知道这不是一个严格的技术问题,如果结构体是由你的老师提供的,你可能有点束手无策,但是,天啊,现在已经是2019年了!学习编写好程序不仅意味着语言的技术性,还要学会编写对用户有益的程序,所以早期养成好习惯是个好主意。

2
这个问题可以使用 std::boolalpha 来解决。 - Hatted Rooster
1
谢谢@SombreroChicken - 我记不清这是否适用于cincout,还没有检查。 - BoBTFish
1
针对你提到的第三个问题...首先,这是一个非常简单的应用程序,只测量医疗患者的4个特征,所以我不明白为什么OP应该包括广泛的性别。其次,这个度量并不是关于性别的,它是一个医疗应用程序,因此很可能是关于生理性别的度量,而在大多数情况下是二元的。你说得对,这不是一个技术问题,但恕我直言,我认为你应该在下一个回答中避免谈论这个问题。 - Walker

2
您不能将字符串true分配到布尔字段中。请检查更正后的示例。翻译为:无法将字符串true赋值给布尔字段。请检查已更正的示例。
int main()
{
    struct Patient
    {
        double height;
        double weight;
        int age;
        bool isMale;
    };
    Patient ListOfPatients[4];
    int iii = 0;

    while (iii < 4)
    {
        string sIsMale = "";

        cout << "enter the height (eg. 1.80 metres) of patient number  " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].height;
        cout << "enter the weight (eg. 80kg) of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].weight;
        cout << "enter the age of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].age;
        cout << "is the patient a male? (true = male or false = female) " << endl;
        cin >> sIsMale;
        ListOfPatients[iii].isMale = sIsMale == "true";

        iii++;
    }

    return 0;
}

2
你可以使用流操作符boolalpha,无需自己进行任何比较:

最初的回答

cin >> std::boolalpha >> cListOfPatients[iii].isMale >> std::noboolalpha;

1
这里的问题在于isMale是一个boolean,而字符串"true"并不等同于boolean!之所以程序没有崩溃,只是顺利地运行到了结尾,是因为cin仍在读取输入流中的旧字符。解决方案很简单,将true或false转换为布尔值,然后使用它们来设置isMale。可以通过以下方式实现:
String toBeConverted;
cin >> toBeConverted;
ListOfPatients[iii].isMale = toBeConverted == "true";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接