【问题标题】:C++ if(!cin) causes loopC++ if(!cin) 导致循环
【发布时间】:2014-05-17 21:43:45
【问题描述】:

我尝试使用 if(!cin) 来验证用户输入是否真的是整数。但是我的程序然后只是进入一个无限循环,从不询问新的输入

do{
    cin >> temp->data;
    if(!cin){
        cout << "Please enter a Number!" << '\n';
        correct=false;
        }
   }while(correct==false);

如果有人可以帮助我,那就太好了:)

【问题讨论】:

标签: c++ cin


【解决方案1】:

当 std::cin 无法读取输入时,会设置相应的错误标志。因此,您想使用 std::cin.clear() 重置标志,以便下一个输入操作可以正常工作,然后使用 std::cin.ignore(..) 跳过所有内容直到新行,以避免类似的格式输入。

while (!(std::cin >> temp->data))
{
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "\nPlease enter a number!" << std::endl;
}

std::numeric_limits&lt;std::streamsize&gt;::max() 返回流可以容纳的最大字符数,以保证整行被忽略。

【讨论】:

  • 我们的解决方案非常接近,但我不确定 seelenkuchen 是否真的打算跳过第一个提示...
  • “请输入一个数字!”感觉像是一条错误消息,以防用户没有按预期输入数字。否则,他有很多方法可以解决这个问题,或者通过在循环外编写另一个 std::cout ,使用逻辑运算符或使用你的答案中的中断。
  • 我认为你的操作员优先级在你的测试中被打破了。 !&gt;&gt; 之前,对吧?
  • 你是对的。事实上,我只是在仔细检查运算符的优先级。
  • 我刚刚注意到“!”在他的消息中,假设不应该有第一个提示,删除我的答案以支持你的。
【解决方案2】:

如果您想进行这种检查,请将cin 中的数据读取到string 并将string 转换为数字:

string str;
do{
    cin >> str;
    if(!cin){
        cout << "Please enter a Number!" << '\n';
        correct=false;
        }
    else{
        istringstream stream(str);
        stream >> temp->data;
        if(!stream){
            cout << "Please enter a Number!" << '\n';
            correct=false;
        }
     }

   }while(correct==false);

【讨论】:

    【解决方案3】:

    使用cin.fail() 检查用户输入是否正确。如果最后一个 cin 命令失败,cin.fail() 返回 true,否则返回 false。此外,您的循环可能是无限的,因此您还必须声明一个else,您将在其中将检查标志correct 设置为true。因此,在用户输入正确输入的情况下使循环条件无效并退出循环(参见下面的代码):

    do{
        cin >> temp->data;
        if(cin.fail()){
            cin.clear();
            cin.ignore(10000, '\n');
            cout << "Please enter a Number!" << '\n';
            correct=false;
         } else {
            correct=true;
         }
    }while(correct==false);
    

    【讨论】:

    • correct = false 移动到do 之前的声明/初始化,然后进行测试} while (!correct);
    • 当您在没有解释的情况下粘贴更正的代码时,OP 将如何从中学习任何东西?
    • 这是一种非常模糊的输入方式。
    • @Veritas Verum quidem dicis。
    • @Veritas 正如你的名字所说,你说的是实话。尽管如此,OP 并没有要求以最优雅和最有效的方式进行输入。他问为什么他的循环是无限的。
    【解决方案4】:

    您的“正确”变量实际上并没有按照您使用它的方式做任何事情。如果correct 不成立,就不可能退出循环;所以你可以取消它,当你读到这个数字时,只需使用一个循环退出命令。

    此外,到目前为止发布的答案都没有处理被关闭的输入。在那种情况下,他们会陷入无限循环。

    // A loop; we will break out when we successfully read a number.
    while ( 1 )
    {
    // Prompt for a number and read it
        cout << "Please enter a Number!" << endl;
        cin >> temp->data;
    
    // Exit loop if we successfully read
        if ( cin )
             break;
    
    // Check to see if we failed due to the input being closed
        if ( cin.eof() )
        {
            cerr << "End of input reached.\n";
            return 0;   // depends what your function returns of course
        }
    
    // reset the error condition that was caused by trying to read an integer and failing
        cin.clear();
    
    // discard anything they previously typed
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    

    从这里开始,一个好的设计是让这段代码本身就是一个完整的函数。然后,您可以在需要安全获取数字时调用该函数,而无需重复代码。函数声明可能是:

    void input_number(int &the_number, std::istream &in, std::string prompt);
    

    它会输出the_number,它会通过抛出异常或依靠调用者检查!cin,甚至返回bool来处理文件结束;任何最适合您的错误处理的整体。

    【讨论】:

    • 忽略成员函数在 eof 处停止,不管指定的字符是什么。
    • @Veritas 希望如此。这与我发布的内容有关吗?
    • 只是说我不明白你在不涉及输入间接的情况下在 eof 的情况下陷入无限循环的原因。
    • cin.eof() 发生时,您的帖子和 40two 的帖子都陷入了无限循环。退出循环的唯一方法是成功读取数字,并且在 eof 之后不会发生这种情况。
    • 不,至少在我的机器上没有。你是如何进入 eof 的?
    【解决方案5】:

    例如,如果您在if 语句中的条件前放置“!”。那应该是一个“非”运​​算符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 2014-06-07
      相关资源
      最近更新 更多