c ++ isalnum无限循环

时间:2011-03-30 11:18:08

标签: c++ isnumeric

问候!

让我们这次切断过多的介绍并直截了当。

我在使用isalnum方法的C ++中遇到了问题。

代码:

int playAgainst = 0;
do
{
    cout << "Who do you want to play against?(1/2)\n";
    cout << "1: Human player\n";
    cout << "2: Computer player\n";
    cin >> playAgainst
} while(!isalnum(playAgainst) && playAgainst != 0);

如代码所示,我正在为用户提供一个选择。与人类对战或与电脑对战。

我想要的是,只要用户输入任何其他内容然后输入整数值(cin&gt;&gt; playAgainst)来重复该问题。但是,如果我输入char或字符串值,它会不断循环。我不是百分百肯定,但很明显,如果问题是,非int值已经保存为playAgainst的值。如果在保存之前输入值是int,我怎么能检查这段代码它?

或者是唯一可能保存为字符/字符串然后检查?

如果是后者,则会出现新问题。 isalnum只接受int作为参数,至少从我所知道的。我如何检查该字符串或char是否为int?

感谢您抽出宝贵时间阅读。并希望我很快接受回复作为回答^^

感谢大家的回答。 我得到了我想要的东西,一切都已经解决了。

我选择接受答案的原因很好......因为最初,它使我的代码按照我想要的方式工作。我想接受多个答案..

6 个答案:

答案 0 :(得分:2)

playAgainst设为char并与'0'进行比较,而不是0。现在,用户必须输入字符'1''2'的ASCII(或任何字符集)代码。

isalnum无法在int的有效范围之外的char上工作,EOF除外。 (它需要int参数的事实是来自C的剩余部分,它具有与C ++不同的整数提升规则。以适应EOF。)

答案 1 :(得分:2)

删除isalnum()支票。 cin >> playAgainst会将除数字之外的任何内容转换为零,这将由第二次检查捕获。请注意,这只是一个选项,因为零不是有效输入。

如果您自己解释字符,

isalnum()很有用,但在这种情况下,流已经为您完成了。

答案 2 :(得分:1)

这是编译器实现isalnum的方式:

int isalnum (int ch)
{
  return (ch >= 'a' && ch <= 'z') || 
         (ch >= 'A' && ch <= 'Z') || 
         (ch >= '0' && ch <= '9');
}

所以你不妨在自己的代码中编写代码片段,它将与isalnum的内联版本等效。

答案 3 :(得分:1)

这是因为你没有清除缓冲区。当输入无效时,你需要从缓冲区清除它,然后你可以继续下一个输入,否则你每次都试图提取相同的输入(失败,因为它是相同的错误输入),从而进入一个无限循环。

答案 4 :(得分:1)

问题是你输入的是int而不是char。如果是的话 输入中的文本不是int,则输入失败。在这种情况下, playAgainst未被修改,失败记忆在std::cin中 直到你明确清除错误。并从一个流输入 错误状态是无操作。您可能想要做的是

  1. 输入单个字符:如果您不想跳过空格,请使用 `std :: cin.get(ch)`或`ch = std :: cin.get()`。 (在后者中 case,`ch`应该是`int`,因为它还必须处理`EOF`。 另一方面,你可以直接使用`:: isalnum`,其中 如果`ch`是`char`。
  2. ,你就做不到
  3. 完全检查有效输入:不仅仅是`:: isalnum`,而是 输入是否是列表中的合法选择器。某物 沿着:
        ch != EOF && std::find( legalChars.begin(), legalChars.end(), (char)ch ) != legalChars.end()
    
  4. 如果出现错误,请清除所有剩余输入,例如:
               std::cin.ignore(INT_MAX, '\n');
    
  5. 在实践中,您可能希望以不同的方式对待EOF 一个错误的命令。 (如果你在EOF之后没有清除输入,那么你 将无法阅读任何其他内容。但据推测,如果你得到EOF, 这是因为用户放弃了,不想再尝试了。)

    最后,保留所有信息可能更为可取 一个共同的位置,使用表格:

    struct Command
    {
        char        op;
        char const* prompt;
        void (*     func)();
    };
    

    然后循环遍历这些表格以输出提示,将其搜索到 看看角色是否合法,最后,调用该函数 你找到的条目。或者定义一个抽象基类,一个具体的类 从每个命令派生出来,并使用std::map<char, AbstractBase*>进行映射等。非常C ++,但也许有点 对于这样一个简单的案件来说过度了。

答案 5 :(得分:0)

为什么不使用isdigit()