(cin)如何评估?

时间:2014-03-11 22:58:25

标签: c++

在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
$
  • 为什么进入&#34; foo&#34;显然导致i设置为0
  • 为什么进入&#34; foo&#34;导致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停止。

  • 再次,为什么进入&#34; foo&#34;显然导致i设置为0
  • 为什么在输入i后,在while循环的下一次迭代中,系统不会提示用户输入foo的新值?

这是使用g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

我很抱歉这么长的问题,但我认为这一切归结为,&#34;如何评估cin?&#34;

2 个答案:

答案 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 iint时,流会尝试从流中提取int。如果成功,i设置为提取的值,一切都很好。如果失败,则设置流badbit。这很重要,因为将流视为bool等同于检查它是否badbit设置为if (cin)

所以无论如何......发生的事情是foo正在设置badbit,因为提取失败了。实际上,您应该检查提取是否成功:

if (cin.good())

在代码质量说明中,我怀疑您正在使用if (cin >> i) { /* success */ } 。请注意can be harmful