istream 循环使程序跳过 cin 语句

问题描述

这是一个程序,它采用一系列以空格分隔的数字,然后将其存储在一个向量中。问题是把cin循环放在x0的输入之前,程序会跳转到下一个cin语句,但是反过来却很正常。

你能向我解释一下我在这里遗漏了什么吗?

跳跃状态:

vector<int> V{};
int x0{},temp{};
        
cout << "Enter sequence\n";
for(temp;cin>>temp;)
{
    if (!isalpha(temp)) V.push_back(temp);
    else
    {
        cin.clear();
        break;
    }
}
cout<<"enter x0 : ";
cin >> x0;// the program skips this!

反向工作:

vector<int> V{};
int x0{},temp{};
cout<<"enter x0 : ";
cin >> x0;
cout << "Enter sequence\n";
for(temp;cin>>temp;)
{
    if (!isalpha(temp)) V.push_back(temp);
    else
    {
        cin.clear();
        break;
    }
}

解决方法

在第一个示例中,您在循环中调用 cin >> temp 直到读取失败,因为输入了非整数,或者用户明确结束输入(使用 Ctrl-CCtrl-Z 或任何您的平台使用的)。然后您尝试调用 cin >> x0 而没有首先清除 cin 的错误状态,因此读取也会失败。

您对 cin.clear() 的调用(不会丢弃 cin 的输入缓冲区中的数据,仅重置 cin 的错误状态)需要在 operator>> 之后完成失败,不是在 isalpha() 检查之后,例如:

vector<int> V;
int x0,temp;
        
cout << "Enter sequence\n";
do
{
    if (!(cin >> temp))
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        break;
    }

    if (isalpha(temp))
        break;

    V.push_back(temp);
}
while (true);

cout << "enter x0 : ";
cin >> x0;

在第二个示例中,您不会在读取失败后尝试调用 cin >> x0,这就是该代码有效的原因(前提是用户实际上为 cin >> x0 输入了一个有效整数,否则 {{ 1}} 将立即失败,因为您没有重置错误状态或丢弃缓冲区中的数据)。