1

这是我的代码:

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”)时,程序无限循环而不是进入默认语句,再次编写问题并让我选择另一个班级。为什么?

4

2 回答 2

1

因为您正在读入一个int,并且读取失败。这有两个效果:

  1. 您对classnum之后的使用是未定义的行为,并且
  2. 流已经记住了错误条件,因此您可以稍后检查。

只要错误条件未被清除,流上的所有进一步操作都是无操作的。使这项工作在您的程序中进行的最简单的更改是:

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,并getline按照 user814628 的建议使用 。以上更多是向您解释正在发生的事情,以及为什么您会看到您看到的症状。user814628 的建议是更好的软件工程。

于 2013-05-22T18:21:41.220 回答
1

Try something like this:

#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){ .... }

The reason why it fails in your case is because cin is trying to read a bunch of chars into a int variable. You can either read it as a string and convert as necessary, or you can check the cin state explicitly when reading into a int variable by checking if any of the fail bits are set. The fail bits would be set if for example you try to read bunch of chars into an int.

于 2013-05-22T18:06:52.407 回答