#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
。
为什么两种情况下的行为不同?
答案 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)
当提取成功时(无论提取的整数是否为正),新行将被吃掉。
当提取失败时,它不会被吃掉。