do while 循环中的 if 语句以 yes 或 no 结尾



我是编码新手,我正在尝试使用嵌套的if语句进行长时间的do while循环,但我在使循环实际循环时遇到问题。

我没有直接获得有关我的项目的帮助,该项目的代码很长,而是制作了一个简单的类似版本。它也不会循环。 它将到达最后并询问用户是否要重试,但是当输入"y"时,它会忽略if语句。

#include <iostream>
#include <string>
using namespace std;
int main()
{
string sodaChoice;
char answer = 'n';
do
{
cout << "Please choose your favorite soda from the following: Rootbeer, Diet Coke, Coke, Sprite" << "n";
getline(cin, sodaChoice);
if (sodaChoice == "Rootbeer")
{
cout << "Me too!" << "n";
}
else if (sodaChoice == "Diet")
{
cout << "Not me :(" << "n";
}
else if (sodaChoice == "Coke")
{
cout << "It's alright" << "n";
}
else if (sodaChoice == "Sprite")
{
cout << "only if I'm sick" << "n";
}
else
{
cout << "That was not on the list";
}
cout << "would you like to try again?";
cin >> answer;

} while (answer == 'y'|| answer == 'Y');


return 0;
}

我想也许我需要在围绕 if 语句的 do 循环中有一个 do 循环,但后来我不知道该怎么做。 任何帮助将不胜感激。我花了很多很多小时试图弄清楚。

我试着问我的老师,但我的大学教他们的院长根据她的书写的一些通用课程。他对帮助或教学不是很热心。

编辑: 谢谢大家的回答!至于这是一个重复的问题,我还没有学习cin.ignore ,所以我不知道它与我的问题有关。 谢谢大家教我!

cin >> answer;

你只读了一个字符。问题是您在编写答案时至少输入了两个字符。实际的'y''n'加上Enter键,该键作为换行符添加到输入缓冲区中。

然后,下一个getline调用将此换行符读取为空行。

这个问题有一些解决方案,例如在读入answer后使用ignore。或者,如果您只需要一个单词输入,那么您也可以使用>>表示sodaChoice的格式化输入,因为它默认情况下会跳过前导空格(如换行符)。

在用户行为良好且仅输入"y"或"n"后跟换行符的情况下,现有答案是正确的。

我们可以通过修改 .ignore() 调用来增加一点安全性,方法是要求它忽略所有字符,包括下一个换行符:

您需要在翻译单元的顶部添加以下标题包含:

#include <limits>

您需要在cin >> answer之前添加此行:

// consumes and ignores as many characters as necessary until a newline. 
// The newline is also consumed.
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');

带有测试输入的完整程序在这里:

http://coliru.stacked-crooked.com/a/996e77559590ad6d

不幸的是,计算机科学教师对计算机科学一无所知并不罕见。不要担心这一点,或者让它让你放弃学习如何编写软件 - 这只是一个症状,即优秀的软件工程师比优秀的教师获得更多的报酬。

以下是一些有用的参考资料: https://en.cppreference.com/w/cpp/io/basic_istream/ignore

我将提出与其他答案完全相反的建议。与其使用cin.ignore跳过您阅读的字符之后的任何额外字符,我认为最好用getline()来完成所有阅读,完全忘记cin >> somevar

原因有二:

  1. 使用cin >> somevar获得的格式化输入会忽略前导空格,包括换行符。如果用户在空行上按Enter键,程序不会执行任何操作,但仍需要进一步的输入。这不是 CLI 程序的用户所期望的!通常的期望是Enter完成输入,空输入应导致程序使用默认值,或抱怨输入无效。有了cin >> somevar,你也做不到。

  2. 格式化输入会将任何不匹配的输入保留在缓冲区中。在您的示例中,读取单个字符至少会留下以下换行符,但其他类型的输入也会发生同样的情况。读取一个数字(带int i; cin >> i;)会在等待下一个输入操作的数字之后留下任何内容,因此输入123 abc将返回123,并且abc将出现在下一个输入操作中。

    其根本原因是,默认情况下,命令行终端处于基于行的模式。在输入完整行之前,程序或库函数看不到来自操作系统的任何输入。(cin.ignore()当然可以帮助你解决这个问题,但不能解决第一点。

使用getline()与底层机制完全匹配,可以处理空输入(以及在读取int时分辨零和非数字之间的区别),并自动处理尾随垃圾。但是,您必须手动将读取字符串转换为您实际想要的任何内容。

在您的情况下,您可以将循环条件简单地更改为如下所示的内容:

string answer;
...
getline(cin, answer);
} while (answer == "y" || answer == "Y");

如果您需要一个数字,您可以使用例如int num = std::stoi(str).


(在 C 中,如果使用scanf()进行用户输入,也会发生同样的情况,同样,最好使用fgets()然后使用sscanf()解析字符串,这提供了相同的选项,但处理行缓冲。我对C++不太熟悉,所以我不知道如何让getline()阅读一整行的cin >> somevar完全相同。

由于您从类型char的用户那里获取输入,但每次Enter键命中,它将换行符 (n) 分配给变量answer

您可以通过在输入行之后添加一行来忽略这一点

cin.ignore();

您可以阅读此内容以获取更多详细信息。

最新更新