2015-10-09 129 views
1
#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; 
} 

上面的代码应该会提示输入,直到输入正整数。但即使输入正整数后,它仍然会提示输入。 例如,可以说我有输入作为使用cin验证输入

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 

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

+1

'b'如何设置为'\ n'? 'b'是一个整数。 –

+0

@KolyolyHorvath变量已被定义。对不起,我忘了 – ibrahim5253

+0

不要“忘记”它。请提供清楚,简洁和精确的[最小测试用例](http://stackoverflow.com/help/mcve),以表明问题**,以便我们不会猜测/假定您可能做或可能没有做过的事情。 –

回答

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几乎是“标准”解决方案。

+0

这就是'忽略'的意思,不是?为什么要提取字符,当你可以跳过它们?这个解决方案与OP的不同之处是什么?至多,它是,你需要解释为什么。更糟的是,事实并非如此。 –

+0

@LightnessRacesinOrbit我试图让它更清晰,代码不是一个替代解决方案,就像插图。 (问题是为什么行为不同,而不是最好的解决方案。) – molbdnilo

0

当提取成功时(取出的整数是否为正值),换行符将被吃掉。

提取失败时不会被吃掉。

+0

那么在第一个代码片段中'cin >> m'究竟发生了什么。 – ibrahim5253

+0

我不知道,因为你没有**显示问题**显示你的输入。为什么不简单地在调试器中逐步执行程序,在每一步检查'm'的流状态和值? –

+0

让输入为'abc' – ibrahim5253