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

时间:2018-10-09 08:58:19

标签: c++ if-statement do-while

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

我没有直接在代码很长的项目上获得帮助,而是制作了一个类似它的简单版本。它也不会循环。它将结束并询问用户是否要重试,但是输入“ 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,所以我不知道它与我的问题有关。谢谢大家教我!

4 个答案:

答案 0 :(得分:13)

使用

cin >> answer;

您准确地读取了一个字符。问题是您在写答案时至少输入了两个个字符。实际的'y''n' plus Enter 键,它作为换行符添加到输入缓冲区中。

此换行符随后在下一个getline调用中作为空行读取。

有一些解决此问题的方法,例如在读入answer之后使用ignore。或者,如果您只想输入一个单词,则也可以将>>用作sodaChoice的格式化输入,因为默认情况下它将跳过前导空白(如换行符)。

答案 1 :(得分:7)

在用户表现良好并仅输入“ 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

答案 2 :(得分:5)

我将提出与其他答案完全相反的建议。我认为与其使用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 ++不太熟悉,因此我无法说出如何使cin >> somevar的行完全等于getline()。)

答案 3 :(得分:0)

由于您正在从类型char的用户那里获取输入,但是每次击键Enter时,它就会将换行符(\n)分配给变量answer。 >

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

cin.ignore();

您可以阅读this了解更多详细信息。