输入流条件检查错误。

3

我是一名学习C++的初学者。我遇到了一个困扰我很久的问题,那就是cin命令。在下面的程序部分中,如果我在第一个cin命令处输入错误的类型,程序将不会执行后续的任何cin命令,但将执行程序的其余部分。

//start
#include <iostream>
using namespace std;
int main()
{
    int x=0;
    cout << endl << "Enter an integer" << endl;

    //enter integer here. If wrong type is entered, goes to else
    if (cin >> x){
            cout << "The value is " << x << endl;
    }
    else {
         cout << "You made a mistake" << endl; //executes
         cin.ignore();
         cin.clear();
    }
    cout << "Check 1" << endl; //executes
    cin >> x;                  //skips
    cout << "Check 2" << endl; //executes
    cin >> x;                  //skips
    return 0;                  
}
//end

如果我把同样的概念放在一个循环中而不是if else语句中:

while (!(cin >> x))

当输入错误时,程序会进入一个无限循环。

请帮我解释这个现象,因为我正在跟随的教材说上面的代码应该按预期工作。

谢谢!


3
先执行 clear(),然后再执行 ignore() - Kerrek SB
谢谢,伙计!现在可以工作了 :) - Muffi
为什么另一种方式不起作用? - Muffi
2个回答

3

cin是一个输入流。如果发生错误,cin会进入一种叫做“错误发生”的状态。在这个状态下,无法进行任何字符输入,你请求从输入流中收集字符的要求将被忽略。使用clear()可以清除错误,输入流停止忽略你。

以下是ignore函数的原型:

istream&  ignore ( streamsize n = 1, int delim = EOF );

这个函数从输入流中获取字符并丢弃它们,但是如果您的流忽略您,则无法获取任何字符,因此您首先必须 clear() 流,然后再 ignore() 它。

另外,需要注意的是:如果有人在第一次输入请求时输入了"abc",则您的 cin 只得到一个字符 'a',而 "bc" 仍然留在缓冲区等待被取走,但下一次调用 cin 会获取 'b' 并且 'c' 仍然留在缓冲区,所以您又遇到了错误。

这个例子的问题在于,如果没有向 cin.ignore() 传递参数,它只会在您 clear() 后忽略1个字符。因此,第二个 cin 获取了 'c',所以您仍然有问题。

解决这个问题的通用方法是调用

cin.ignore(10000, '\n');

第一个数字只需要是一个你不认为任何人会输入的巨大数字,我通常输入10000。

这个调用确保你从错误输入中捕获所有字符,或者在按下回车之前捕获每个字符,这样你的输入流就不会两次进入“发生错误”的状态。


谢谢CodeJunkie,我在修正代码后遇到了这个问题。经过一些搜索,我发现了cin.sync(),它可以清除整个现有的输入流。我用cin.ignore()替换了它,也起作用了!! - Muffi

0
您可能还想尝试使用以下代码作为备选项,以避免在提示输入时由于错误类型的输入而导致崩溃:
``` if ( std::cin.fail() ) ```

你能详细说明一下那会如何有帮助吗? - SamB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接