首先注意:

1、每一个输入(输出)对象就代表一个输入(输出)流;

2、输入(输出)对象中的流状态成员标记了输入(输出)流当前的状况,当eofbit、badbit、failbit三个标记位均为0时表示流状态正常;

3、一但某个或几个标记位被设置,表示对象的流状态出现相应状况,流将对后面的输入(输出)关闭,直到标记位被清除;

4、只有在流状态良好的情况下,if或者while对该输入(输出)对象的判断才能是ture。

接下来看看这个程序:

 #include <iostream>
using namespace std; int main()
{
int input;
while (cin >> input)
{
cout << input << endl;
cout << "rdstate()函数的返回值: " << cin.rdstate() << endl;
cout << "三个标记位返回的返回值: " << cin.bad() << cin.fail() << cin.eof() << endl;
cout << "goodbit标记位的返回值: " << cin.good() << endl;
cout << endl;
} cout << "rdstate()函数的返回值: " << cin.rdstate() << endl;
cout << "三个标记位返回的返回值: " << cin.bad() << cin.fail() << cin.eof() << endl;
cout << "goodbit标记位的返回值: " << cin.good() << endl; if (!cin)
cout << "input error" << endl; else
cout << input << endl; system ("pause");
return ;
}

当输入为:“123 124 158 137a”时,输出为:

具体分析如下:

123、124、158均被正常抽取,从rdstate()等 流状态标记位测试函数的返回结果可以看出来。

当轮到137a进入程序时,抽取操作符将137成功抽取,将a留在输入流中。抽取操作符“  >>  ”返回cin对象,此时流状态仍为正常,failbit、eofbit、badbit三个标记位的值均为0。然后while判定cin对象为true,使得进入循环输出137及流状态信息。

接下来进入下一次循环,执行 cin >> input ;   语句:a为输入流的第一个字符,a与input变量类型不匹配,导致cin流状态的failbit标记位被置为1(goodbit标记位被置为0),这使得“  >>  ”返回的cin对象自身检测为False, 然后while判定cin对象为false,退出循环。而字符a,留在了输入流中。

退出循环后输出cin的流状态,可以看出,rdstate()的结果是4,failbit标记位为1,goodbit标记位为0。

程序流程到了 if  语句,此时cin对象的failbit标记位已经被置为1(goodbit标记位被置0),if 判定cin对象为false ,那么 !cin 为true,因此输出input   error。

当输入文件结束符(^Z,即Ctrl+Z 或 F6)时,输出为:

badbit 标志着系统级的故障,如无法恢复的读写错误。如果出现了这类错误,则该流通常就不能再继续使用了。如果出现的是可恢复的错误,如在希望获得数值型数据时输入了字符,此时则设置 failbit 标志,这种导致设置 failbit的问题通常是可以修正的。eofbit 是在遇到文件结束符时设置的,此时同时还设置了 failbit。

流的状态由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof中的任意一个为 true,则检查流本身将显示该流处于错误状态。类似地,如果这三个条件没有一个为 true,则 good 操作将返回 true。

再来看一看下一段代码:

 if   (cin   >>   input)
cout << input << endl;
else
cout << "input error" << endl; if (!cin)
cout << "input error" << endl;
else
cout << input << endl;

当输入为567a时,输出为:

567

567

原因:输入流中的567被“   >>   ”抽取到  input  中,因此抽取操作符“   >>   ”返回的cin对象的流状态成员正常。因此 !cin  为false,使得再一次输出567。注意:字符a留在了输入流。

但当代码重复一次时:

 if   (cin   >>   input)
cout << input << endl;
else
cout << "input error" << endl; if (!cin)
cout << "input error" << endl;
else
cout << input << endl;
//第一次代码结束 if (cin >> input)
cout << input << endl;
else
cout << "input error" << endl; if (!cin)
cout << "input error" << endl;
else
cout << input << endl;
//重复代码结束

如果输入567a,输出是:

567

567

input   error

input   error

原因是:当第一次代码正常完成后, 第二次代码开始,输入流中的第一个字符是a,a与input不匹配,“   >>   ”无法抽取, 抽取操作符“   >>   ”函数返回的cin对象,其failbit标记位被置为1(goodbit标记位被置为0)  ,cin的自测为False,if  判定条件为false;且导致下一个if语句:  if   (!cin)    中, cin对象为false, !cin  为true。

真相是:只要抽取操作符“   >>   ”能成功抽取输入流中的数据,哪怕只是部分匹配,cin对象的流状态成员(即标记位)不会被设置,流状态仍将保持正常。

一旦输入完全不匹配,“   >>   ”无法进行任何抽取,返回的cin对象其failbit标记位置为1(goodbit标记位被置0),cin流状态出现相应状况 ,且在恢复之前,流将对后面的输入关闭。

不对之处,敬请指教。

参考文献:http://blog.csdn.net/ygj149078299/article/details/538998

关于if (!cin)以及while (cin >> word)的更多相关文章

  1. [原创]cin、cin.get()、cin.getline()、getline()、gets()、getchar()的区别

    这几个输入函数经常搞不清具体特点和用法,这里稍作总结 一.cin>> 1.最基本用法,输入一个变量值 2.输入字符串,遇“空格”.“TAB”.“回车”结束,比如输入“hello world ...

  2. C++中关于cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    1.cin>> 用法1:最基本,也是最常用的用法,输入一个数字: 注意:>> 是会过滤掉不可见的字符(如 空格 回车,TAB 等) cin>>noskipws> ...

  3. C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法----细节决定成败 (sort用法)

    C++中cin.cin.get().cin.getline().getline().gets()等函数的用法 学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有 ...

  4. C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行) 1.cin 2.cin.get ...

  5. cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行)转载请保留作者信息:1.cin1 ...

  6. [转载]cin、cin.get()、cin.getline()、getline()、gets()函数的用法

    1.cin>>           用法1:最基本,也是最常用的用法,输入一个数字: #include <iostream>using namespace std;main ( ...

  7. (转)cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行)转载请保留作者信息:1.cin1 ...

  8. cin详解(cin.get()、cin.getline()、cin.clear()、cin.sync())

    在C中,输入输出用scanf和printf,在输入数据的同时还需说明数据的类型,如果输入数据较多,那就很麻烦,而C++中也有相似的东西cin和cout,它们来自C++的一个名叫" iostr ...

  9. C++中几个输入函数的用法和区别(cin、cin.get()、cin.getline()、getline()、gets()、getchar())

    1.cin>> 用法1:最基本,也是最常用的用法,输入一个数字: #include <iostream>using namespace std;main (){int a,b; ...

随机推荐

  1. 国内常用ntp服务器ip地址

    ntp.sjtu.edu.cn 202.120.2.101 (上海交通大学网络中心NTP服务器地址)s1a.time.edu.cn 北京邮电大学s1b.time.edu.cn 清华大学s1c.time ...

  2. Wireshark入门与进阶系列(二)

    摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...

  3. 杭电 HDU 4608 I-number

    http://acm.hdu.edu.cn/showproblem.php?pid=4608 听说这个题是比赛的签到题......无语..... 问题:给你一个数x,求比它大的数y. y的要求: 1. ...

  4. UML视图(四)状态图

    以下是一个图书馆管理系统的状态图,非常典型,涵盖状态图的全部元素的使用,由于状态图相对照较简单,直接从看图就能非常好地掌握.假设想对状态图的元素严谨的概念进行了解,在图下方,有仔细的叙述. 看了上面的 ...

  5. 运用Autoconf和Automake生成Makefile的学习之路

    作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的M ...

  6. 依赖注入及AOP简述(八)——混合请求模式 .

    2.3.    混合请求模式 上一节讲到了FQCN(全类名)请求模式会带来依赖定义的柔软性较差的问题,因此字符串和全类名混合的模式又应运而生了.比如刚才的Spring中的API方式声明注入点的例子就可 ...

  7. javascript设计模式——Publish/Subscribe

    推荐阅读http://dev.housetrip.com/2014/09/15/decoupling-javascript-apps-using-pub-sub-pattern/ 我们先引出问题的所在 ...

  8. Android中view的事件

    view:top.left.right.bottom,相对于parent的位置参数,获取通过get*()来获取.width=right-left.height=bottom-top.x=left+tr ...

  9. Qt5 多显示器获取不同显示器的分辨率和位置的方法

    Qt5 多显示器获取不同显示器的分辨率和位置的方法 先放官方文档链接:QDesktopWidget - Qt5 Reference 之前一直在用被我乱搞后的ShadowPlayer作为默认播放器,后来 ...

  10. GitHub问题之恢复本地被删除的文件

    折腾了真久,GitHub commit之后,我手痒把本地的一个文件给删了,然后一直Git pull都发现不能恢复.远程库里面还是有该文件的.就是我想将远程库的文件回到本地被删除了的位置. 特别的是,我 ...