更智能的方式来实现此switch语句

时间:2014-11-04 01:38:20

标签: c++ options cin

所以我试图让用户做出选择,但我有问题。以下几行

cout << "\nWhat would you like to do? " << endl
    << "(1) Display the entire List" << endl
    << "(2) to exit" << endl;

getline(cin,answer);
answerint=stoi(answer);
switch (answerint) {
    case 1:
        showLIST(myLIst);
        break;
    case 2:
        return;
    default:
        cout << "\nPlease choose from the list";
   }

因此,如果用户选择一个整数,这可以正常工作,但如果收到一个字符则会barfs。我怎样才能减少这种不易破碎?

2 个答案:

答案 0 :(得分:1)

看起来你想要这样的东西:

if (std::cin >> answerint) {
    switch (answerint) {
        // ...
    }
}

直接从流中转换整数会使流进入失败状态,以防输入与int不同的内容。您可能需要添加一个操纵器以确保该行末尾没有非空格字符。

答案 1 :(得分:0)

std::string answer;
int answerint;
while (std::getline(std::cin, answer))
{
    std::istringstream iss(answer);
    char c; // seek non-whitespace after the number?
    if (!(iss >> answerint) || (iss >> c))
        answerint = 0;
    switch (answerint)
    {
      ...as you had...
    }
}

上面的代码使用getline来确保将完整的文本行解析为answer,之后它会从该单行创建一个不同的std::istringstream。这样,我们可以使用>>知道它不会跳过新行消耗或等待进一步输入。

if (!(iss >> answerint) || (iss >> c))检查是否没有要解析为answerint的数字,或者在解析数字后,该行上会出现另外的非空白字符。例如,输入的行可能是2r - 我们会考虑错误并重新选择一个选项,将0分配给answerint以确保我们到达default switch中的标签,从而打印cout << "\nPlease choose from the list"; 2r,与99或其他任何内容相同......

以这种方式使用getline和单独的istringstream,您可以可靠地尝试从已知状态解析下一行输入。