标准输入cin的返回值以及while(cin>>x)的问题
最近在看C++,学到了标准库这一章,看到cin的时候,我们经常看到很多的代码中会有这么一段while(cin>>x){ ......}。这里我们最关注的问题是while括号里面cin>>x他每次输入的时候返回的是什么值呢。所以我们也就会问cin的返回值是什么。我也看到很多像我这样的新手问这样的问题,下面说下我个人的见解,如有不当之处,还请指正!
其实我倒觉得我们这个问题问错了,我们不应该问cin返回值是什么,我觉得我们应该关注">>"输入操作符,其实是它到底返回了什么。因为cin是标准输入istream的一个对象,一个对象能返回什么吗?对象有返回值吗?好像没有吧!在C++primer里面讲到过,cin>>x>>y。有这么一行代码,我们讨论下">>"这个输入操作符,这个操作符接收一个istream对象作为其做操作数,接收一个对象作为其右操作数。">>"操作符返回其左操作数作为结果,这样也就可以解释为什么上面可以将两个输入操作合并了。因为cin>>x返回cin对象,接着又可以进行cin>>y。所以我们就可以顺利进行输入了。所以我们再来看上面的那个while循环,里面的cin>>x,返回的是cin对象(注意是输入操作符“>>”返回),所以返回的也就可以认为是流本身了。我们再来看下他什么时候退出循环。因为我们已经知道了括号里面的返回值了,所以我们看看它什么时候退出循环。
输入(cin)缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin 就会检测输入缓冲区中是否有了可读的数据,这种情况下cin对键盘上是否有作为流结束标志CTRL+Z或者CTRL+D,其检查的方式有两种:阻塞式以及非阻塞式。这里借用一点网上搜到的资料,
阻塞式检查方式指的是只有在回车键按下之后才对此前是否有 Ctrl+Z 组合键按下进行检查,非阻塞式样指的是按下 Ctrl+D 之后立即响应的方式。如果在按 Ctrl+D 之前已经从键盘输入了字符,则 Ctrl+D的作用就相当于回车,即把这些字符送到输入缓冲区供读取使用,此时Ctrl+D不再起流结束符的作用。如果按 Ctrl+D 之前没有任何键盘输入,则 Ctrl+D 就是流结束的信号。
阻塞式的方式有一个特点:只有按下回车之后才有可能检测在此之前是否有Ctrl+Z按下。还有一个特点, Windows下是不用CTRL+D的,如果在你的程序中使用CTRL+D的话,如果你还有要输入的数据的话,会直接挂掉的,不能再输入了。Windows下是使用CTRL+Z的。 在你输入CTRL+Z后,括号里面的数据变为0000 0000了。来看一段程序:(vc6.0上运行)
#include <iostream> using namespace std; int main(void) { int i; cout<<(cin>>i)<<endl; return 0; }
当你按下CTRL+Z后,按下两次回车,就可以得到结果0000 0000.所以上面的while会退出循环。但是当你在你的程序中输入数据的时候,你要结束输入,你输完数据直接回车,再按下CTRL+Z,再按下回车就可以结束了。因为前面说过如果输入缓冲区中有可读的数据则不会检测 Ctrl+Z(因为有要读的数据,还不能认为到了流的末尾)。还有一点需要知道,Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。差不多就这么多了,个人看法,有不当之处还请大家指点!谢谢!