我是编码新手,我正在尝试使用嵌套的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
。
原因有二:
-
使用
cin >> somevar
获得的格式化输入会忽略前导空格,包括换行符。如果用户在空行上按Enter键,程序不会执行任何操作,但仍需要进一步的输入。这不是 CLI 程序的用户所期望的!通常的期望是Enter完成输入,空输入应导致程序使用默认值,或抱怨输入无效。有了cin >> somevar
,你也做不到。 -
格式化输入会将任何不匹配的输入保留在缓冲区中。在您的示例中,读取单个字符至少会留下以下换行符,但其他类型的输入也会发生同样的情况。读取一个数字(带
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();
您可以阅读此内容以获取更多详细信息。