【问题标题】:Switch case inside a while(true) loop在 while(true) 循环内切换大小写
【发布时间】:2021-11-29 22:32:34
【问题描述】:
int main() {
    int choice;
    
    while (true){  
        cout << "Enter choice: \n";
        cin.clear();
        cin >> choice;
        switch(choice){
            case 1:
                cout << "you picked 1\n";
                break;           
            case 2:
                cout << "you picked 2\n";
                break;
            default:
                cout << "invalid choice\n";
                break;         
        }
    }
}

大家好!你能帮我么?我制作了一个有多个选项可供选择的程序。问题是当我输入一个整数以外的东西时,它给了我一个无限循环。如何抛出错误并返回输入?

【问题讨论】:

  • 了解 can.fail() 和 cin.clear()。
  • 检查cin的状态。喜欢if (cin &gt;&gt; choice) { switch (...) ... } else { /* Handle invalid input */ }
  • 为了更好地验证输入,将整行读入std::string(例如std::getline),然后尝试解析该字符串。
  • cin 可以在 if (..) 条件内进行验证 - 它有一个隐式转换运算符,可以根据 last 返回 True/False上次操作是否成功。如果您尝试在 choice 中输入任何不是整数的其他内容 - cin 将评估为 false (if (cin >> choice) {...})。并且无论如何,您编写代码的方式总是会陷入无限循环。 break 会导致从 switch case 中退出,但是你是从 while 循环中中断的?
  • 如果您输入的不是整数(例如字母X),那么cin 将被置于错误状态,并且违规字符将留在流缓冲区中。如果下一个操作尝试再次读取整数(就像在循环中所做的那样),那么将再次遇到有问题的字符(因此流保持错误状态并且字母保持在缓冲区中导致错误)。读取积分输入后,检查流状态(例如cin.fail()!cin 将测试为真)并清除它(例如cin.clear())。

标签: c++ loops switch-statement infinite-loop options


【解决方案1】:

你的问题已经有很多很棒的问题了,我只是想给你一些提示,并指出一些链接,以便从中学习一些东西。

首先,不要忘记始终使示例代码完全工作并准备好编译:

  1. 你忘了包含&lt;iostream&gt;
  2. 您使用了 cin/cout,但没有各自的命名空间 (std::)
  3. 你应该,也许,更多地构造代码,使用一个函数来指出你在做什么 - 比如:getChoiceFrom(std::istream&amp; stream, int&amp; choice)printChoices(int choiceIGot) - 是的,有更好的选择,但你知道按自己的方式工作通过那些学习 What's the difference between passing by reference vs. passing by value?

对于第一部分,您可能已经完成了这些工作,但我建议您查看:Why is "using namespace std;" considered bad practice? - 也许您已经知道这一点 - 但我们无法从您的示例中看出。

让我们重写一些代码(我会尽量保持与原始代码尽可能接近):

#include <iostream>
#include <limits>

int main() {
    // I'd advise against it, but you could at least do:
    using std::cout;
    using std::cin;
    // instead of using namespace std, which I assume you did
    // OR, again, not recommended but at least limit the scope of
    // using namespace std;
    
    int choice;
    
    while (true){  
        cout << "Enter choice: \n";
        // `std::cin` (converts to `bool` indicating errors or lack thereof) - https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool
        // this is the concise version but you can also split it
        // it works because cin returns a reference to self when doing operator >> - also called insertion or put - https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt2
        if(!(cin >> choice)) {
            cout << "invalid input! please enter a number\n";
            // clear the error state of this input stream
            // docs: https://en.cppreference.com/w/cpp/io/basic_ios/clear
            cin.clear();
            // ignore all the input that was passed by the user until a certain max limit
            // https://en.cppreference.com/w/cpp/io/basic_istream/ignore
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            // here you can:
            // 1) continue the loop and re-ask for input
            // continue;
            // 2) get out of the loop and end the program (seems that that's what you want to do
            break;
        }
        switch(choice){
           case 1:
                cout << "you picked 1\n";
                break;           
            case 2:
                cout << "you picked 2\n";
                break;
            default:
                cout << "invalid choice\n";
                break;
        }
    }
}

您还应该研究 c++ 提供的语法糖(运算符和所有)会发生什么。第一步是使用cpp insights

https://cppinsights.io/s/15b32b55

点击Play 按钮。注意到我提到的关于operator booloperator! 的事情了吗?它们在右侧清晰可见。没有糖了。

复制粘贴我提供的示例可能就足够了,但我强烈建议您花时间了解我在 cmets 中指出的所有这些内容。

相信我,从长远来看,这是值得的。愉快地学习 C++!

【讨论】:

  • 感谢您的详细解释和建议,先生。我很感激。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 2020-08-13
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多