如果do while循环中的语句带有yes或no结尾

JKi*_*isa 15 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;
}
Run Code Online (Sandbox Code Playgroud)

我想也许我需要围绕if语句的do循环中的do循环,但后来我不知道如何去做.任何帮助,将不胜感激.我花了很多很多时间试图解决这个问题.

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

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

Som*_*ude 13

cin >> answer;
Run Code Online (Sandbox Code Playgroud)

你只读了一个字.问题是你在写答案时输入了至少两个字符.实际'y''n' Enter键,其中加入作为在输入缓冲器换行.

然后,下一个getline调用将该换行读取为空行.

这个问题有一些解决方案,例如ignore在阅读之后使用answer.或者,如果你想只有一个字的输入,那么你可以使用使用格式化输入>>sodaChoice过,因为它会默认跳过前导空格(如新行).


Ric*_*ges 7

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

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

您需要在翻译单元的顶部添加此标头包含:

#include <limits>
Run Code Online (Sandbox Code Playgroud)

你需要在之前添加这一行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');
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


ilk*_*chu 5

我将提出与其他答案完全相反的建议.cin.ignore在你阅读的那个字符之后,我没有使用跳过任何多余的字符,我认为最好还是完全getline()忘掉所有的阅读cin >> somevar.

有两个原因:

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

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

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

使用getline()完全匹配底层机制,让您处理空输入(以及在读取时告诉零和非数字之间的区别int),并自动处理尾随垃圾.但是,您必须手动将读取的字符串转换为您实际需要的字符串.

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

string answer;
...
    getline(cin, answer);
} while (answer == "y" || answer == "Y");
Run Code Online (Sandbox Code Playgroud)

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


(在C中,如果scanf()用于用户输入,同样会发生,同样,最好使用fgets()然后解析字符串sscanf(),它提供相同的选项但处理行缓冲.我不太熟悉C++,所以我无法告诉如何获得cin >> somevar与完整行读取的完全等价getline().)