在Bjarne Stroustrup的使用C ++编程原则和实践(第六次印刷,2012年11月),if (cin)
和if (!cin)
在第148页介绍并使用认真地写在第178页。 while (cin)
在第183页介绍,并在第201页认真使用。
然而,我觉得我并不完全明白这些结构是如何运作的,所以我正在探索它们。
如果我编译并运行它:
int main()
{
int i = 0 ;
while (cin) {
cout << "> ";
cin >> i ;
cout << i << '\n';
}
}
我得到类似的东西:
$ ./spike_001
> 42
42
> foo
0
$
i
设置为0
?cin
设置为false
?或者,如果我运行并编译它:
int main()
{
int i = 0 ;
while (true) {
cout << "> ";
cin >> i ;
cout << i << '\n';
}
}
我得到类似的东西:
$ ./spike_001
> 42
42
> foo
> 0
> 0
...
此处用户输入的最后一部分是foo
。输入之后,程序会反复将行> 0
打印到stdout,直到用Ctrl + C停止。
i
设置为0
?i
后,在while循环的下一次迭代中,系统不会提示用户输入foo
的新值?这是使用g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
。
我很抱歉这么长的问题,但我认为这一切归结为,&#34;如何评估cin?&#34;
答案 0 :(得分:1)
好吧,std::cin
(或者更确切地说是std::basic_ios
)有一个operator bool
,可以在请求时将std::cin
对象隐式转换为bool
(例如,您的if
评估。
语义如下:
检查流是否没有错误。如果流没有错误并且已准备好进行I / O操作,则返回
true
。具体来说,返回!fail()
。
为什么进入&#34; foo&#34;显然导致我被设置为0?
再次,为什么进入&#34; foo&#34;显然导致我被设置为0?
因为operator>>
上的int
需要字符串中的整数。
来自cppreference
:
如果提取失败(例如,如果输入了预期数字的字母),则值保持不变,并设置failbit。
为什么进入&#34; foo&#34;导致cin被设置为false?
因为设置了失败位,因此导致fail()
返回true
。
为什么输入foo后,在while循环的下一次迭代中不会提示用户输入i的新值?
这是因为std::cin
设置了失败位,因此无法获取输入,只打印i
的{{1}}的旧值。
答案 1 :(得分:1)
在流上使用>>
运算符时,尝试从字符串中提取该类型的值。换句话说,当cin >> i
i
为int
时,流会尝试从流中提取int
。如果成功,i
设置为提取的值,一切都很好。如果失败,则设置流badbit
。这很重要,因为将流视为bool等同于检查它是否badbit
设置为if (cin)
。
所以无论如何......发生的事情是foo正在设置badbit,因为提取失败了。实际上,您应该检查提取是否成功:
if (cin.good())
在代码质量说明中,我怀疑您正在使用if (cin >> i) { /* success */ }
。请注意can be harmful。