在while循环中的switch语句无限循环

时间:2013-05-22 18:02:30

标签: c++ while-loop int switch-statement

这是我的代码:

int main()
{
    int nothing;
    string name;
    int classnum;
    bool classchosen;
    string classname;

    cout << "Welcome adventurer, your journey is about to begin.\n\n";
    cout << "Firstly, what's your name? ";
    cin >> name;
    classchosen = false;
    while (classchosen == false)
    {
        cout << "\n\nNow, " << name << ", choose your class entering its number.\n\n";
        cout << "1- Warrior\n" << "2- Mage\n" << "3- Paladin\n" << "4- Monk\n\n";
        cout << "Class number: ";
        cin >> classnum;
        switch(classnum){
            case 1:
                    classname = "Warrior";
                    classchosen = true;
                    break;
            case 2:
                    classname = "Mage";
                    classchosen = true;
                    break;
            case 3:
                    classname = "Paladin";
                    classchosen = true;
                    break;
            case 4:
                    classname = "Monk";
                    classchosen = true;
                    break;
            default:
                    cout << "\nWrong choice, you have to enter a number between 1 and 4.\n" << endl;
                    break;
        }
    }
    cout << "\nSo you are a " << classname << " ? Well, tell me something more about you...\n";
    cin >> nothing;
    return 0;
}

现在,当我在询问类号时运行它并输入一个字符串(例如“fjdfhdk”)时,程序无限循环而不是进入默认语句,再次写入问题并让我选择另一个类。为什么呢?

2 个答案:

答案 0 :(得分:1)

尝试这样的事情:

#include <sstream>
#include <string>
using namespace std;

int getInt(const int defaultValue = -1){
  std::string input;
  cin >> input;
  stringstream stream(input);
  int result = defaultValue;
  if(stream >> result) return result;
  else return defaultValue;

}

//..in main
cout << "Class number: ";
int classNum = getInt();
switch(classNum){ .... }

在你的情况下它失败的原因是因为cin试图将一堆字符读入一个int变量。您可以将其作为字符串读取并根据需要进行转换,也可以通过检查是否设置了任何失败位来读取int变量时显式检查cin状态。如果您尝试将一堆字符读入int中,则会设置失败位。

答案 1 :(得分:1)

因为您正在阅读int,并且读取失败。这个 有两个影响:

  1. 之后使用classnum是未定义的行为,
  2. 流已经记住了错误情况,所以你可以 稍后检查一下。
  3. 只要未清除错误条件,所有进一步 流上的操作是no-ops。最简单的变化 你的计划是:

    std::cin >> classnum;
    if ( !std::cin ) {
        classnum = 0;
        std::cin.clear();
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    }
    switch ( classnum ) // ...
    

    如果出现错误,则会将classnum设置为已知值, 清除错误状态,并跳过所有输入到下一个 新队。 (否则,你会再次失败,因为 触发错误的字符仍然存在。)

    但是,请考虑使用单独的函数来提取int, 并根据user814628的建议使用getline。以上 更多的是向你解释发生了什么,以及你为什么看到 你看到的症状。 user814628的建议要好得多 软件工程。