用cin验证输入

时间:2015-10-09 11:42:30

标签: c++

#include<iostream>
#include<limits>

int main()
{
    int m;
    std::cin >> m;
    while (std::cin.fail() || m <= 0) {
        std::cin.clear();
        std::cin >> m;
    }
    return 0;
}

上述代码应该提示输入,直到输入正整数。但即使输入正整数后,它仍然会提示输入。 例如,假设我输入为

abc
c4
-3
1
2
.
.

因此,原则上,当我输入1时,执行应该转出循环。但它不断提示输入,看起来像一个无限循环。

环顾四周后,我将其修改为

cin >> m;
while (cin.fail() || m <= 0) {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(),'\n');
    cin >> m;
}

根据需要,输入正数会终止循环。 我没有得到它。为什么新行字符卡在输入缓冲区中? 假设我有这个

int a , b;
cin >> a;
cin >> b;

当我输入

1
2

它正确地将a设置为1而将b设置为2,而不是将b设置为\n。 为什么两种情况下的行为不同?

2 个答案:

答案 0 :(得分:1)

并不是说有一个流浪的换行符,而是整个输入仍在流中。

cin >> m如果无法提取整数,则会立即失败 它不读取下一个“单词”并查看它是否为整数,然后在该“单词”之后停止,如果不是 - “读指针”保留在初始失败点。

ignore向前跳到该行的末尾并忽略到该点为止的所有内容。

为了说明不同之处,该程序首先尝试将输入读取为int,如果失败,则再次读取与std::string相同的输入,以便在错误消息中使用:

int main() {
    int n = 0;
    string s;
    while (!(cin >> n))
    {
        cin.clear();
        cin >> s;
        cout << "That wasn't an int, it was " << s << endl;
    }
    cout << "This is an int: " << n << endl;
}

您使用ignore找到的解决方案几乎就是“标准”解决方案。

答案 1 :(得分:0)

当提取成功时(无论提取的整数是否为正),新行将被吃掉。

当提取失败时,它不会被吃掉。