cin的个人理解
2011-08-09 18:48
148 查看
标准输入设备cin是指从键盘输入数据 , 而我们知道从键盘输入的时候是使用了缓冲的(windows中是行缓冲) ,系统将输入数据放到程序的缓存内存中是以Enter键为标志的。
也就是说 我们输入了一行数据(可以只一个字符或者N个字符时)时,这些数据先是被系统检测到后存放在系统的某处(如系统中的内存,但不是程序的内存中), 而只有当我们按下Enter键后,系统才会将输入的这一行数据存放到我们的程序的输入缓存中.
例如:假设我们程序的输入缓存用char buf[MAX_SIZE]数组表示,
那么当我们遇到第一条输入语句cin>>x>>y>>z;(假设为char类型),由于是第一次程序中的第一条输入,故此时的输入缓存还是空的。程序运行到此处时会先检测自已的输入缓存是否为空。如果为空,则会再检测是否遇到结束符EOF (EOF标志并不出现在输入缓存中) 。如果遇到EOF,则输入语句直接返回;如果没有遇到EOF结束标志,则输入操作将阻塞,即程序暂停等待用户输入。
然后我们开始输入数据,但是在我们按下回车符之前,行缓存都一行为空,程序就一直等待。直到我们按下Enter后,
我们输入的数据比如为"abcde"才会被系统存放到程序的输入缓存中。这时候cin>>x>>y>>z;就会发现输入缓存不为空了。然后x,y,z就会分别读入数据了。x='a' ,y ='b', z= 'c'; 注意,此时程序的输入缓存中的数据并没完 即”de" 还在缓存里。
程序继续运行到某处的输入语句cin>>u>>v >>w; (也为char类型) ,然后发现输入缓存中还有数据,则u = 'd' ,v = 'e'; 但将给w赋值的时候发现没数据了,此同就同上了,程序又开始等待 (同上) .
验证程序(c++):
第一次输入abcde
第二次输入f
输出结果:x='a',y='b',z='c',u='d',v='e',w='f'
再来看看输入类型不相符时的情况:
再此之前,先来简单说下cin这个istream类的个人理解。
cin为输入流对象,在iostream头文件中.
这个cin对象,里面有个标志位成员变量flag(假设)是用来指示cin是否遇到过错误(0为error, 1 为OK)。比如:cin>>x; (x为int型) , 但是我们确输入的是字母. 这时候cin的那个错误标志就会被置为false(即遇到错误) 。 此标志位被置为false后,就代表cin对象遇到错误了,这个位不会自动恢复正常。 然后后面的输入语句cin>>y等等,就都会直接结束了。而不会阻塞等待用户输入了。 直接结束的意思是后面的输入无效(但程序并不会中止),比如上面的y 就不变,相当于没有执行cin操作一样.
要使cin从错误变为正常可以用 cin.clear()语句清除错误.
大家应该见过此类的表达式
if(cin) 或者while(cin)
//do process
这个表达式是什么意思呢? cin本来是一个istream对象呀,如何用非bool来来作测试条件呀? 这里cin的实现里应该重载了一个(bool)cin强制转换为bool量,那这个强制转换成啥呀? 即上面的标志位flag了, 若flag为真,则此条件也为真,若为假,则此条件也就为假了.
下面看个具体的例子:
当为语句int x; 程序中有条输入语句cin>>x; 我们来看看情况会如何?
程序运行的流程还是会一样,先检测输入缓存,若为空,则检测EOF标志。若无EOF标志,则等待输入。
当程序运行到cin>>x时,我们输入了一个字符a,再按下回车。输入缓存中就为 'a'了。
程序检测输入缓存,发现不为空。然后就读依到字符'a'了。但是发现a不是数字呀!! 此时cin的标志位就会置为false,即遇到错误。
但是现在的输入缓存中会变成什么样呢? 程序发现'a'不是数字后,会将其再次放到输入缓存中.即输入缓存还是为'a';
验证程序如下:
再来看看while(cin>>x)结束的方式 (x为任意类型)
1.可以用 上面的方法,使cin的标志位置为false.但这种方法得在while后面再用cin前,使用cin.clear()清除错误。 (cin>>x的返回值为cin的引用.相当于cin>>x,while(cin){})
2.可以在输入新的一行时输入^z (键盘上按下 ctrl+z) 回车,这种情况下cin也标志位也会置为false. 注意:^z得出现在输入的每行的第一个才有效!
下面就我个人理解来解释下 ^z:
^z 相当于文件输入流的EOF标志。
从上面可知cin>>x的时候,程序是先检测输入缓存是否为空。若为空,则再检测EOF标志。若无EOF,则程序等待用户输入。注:^z并不会进入到输入缓存中
每按一次回车时候,程序就执行下上面的步骤。
我们可以认为 ^z 符号只在一次回车时有用。即当输入 'abc'^z的时候, 程序执行不到检测EOF时,就已经有输入了(此时这次的^z就已经失效了,因为它的前面有输入了)
故:^z ( ctrl+z)结束时,得在行首输入! 后面要再次使用cin时,得再调用cin.clear();
验证如下:
本文完。如有错误,还请各个高手指正。
转载请注明出处.
也就是说 我们输入了一行数据(可以只一个字符或者N个字符时)时,这些数据先是被系统检测到后存放在系统的某处(如系统中的内存,但不是程序的内存中), 而只有当我们按下Enter键后,系统才会将输入的这一行数据存放到我们的程序的输入缓存中.
例如:假设我们程序的输入缓存用char buf[MAX_SIZE]数组表示,
那么当我们遇到第一条输入语句cin>>x>>y>>z;(假设为char类型),由于是第一次程序中的第一条输入,故此时的输入缓存还是空的。程序运行到此处时会先检测自已的输入缓存是否为空。如果为空,则会再检测是否遇到结束符EOF (EOF标志并不出现在输入缓存中) 。如果遇到EOF,则输入语句直接返回;如果没有遇到EOF结束标志,则输入操作将阻塞,即程序暂停等待用户输入。
然后我们开始输入数据,但是在我们按下回车符之前,行缓存都一行为空,程序就一直等待。直到我们按下Enter后,
我们输入的数据比如为"abcde"才会被系统存放到程序的输入缓存中。这时候cin>>x>>y>>z;就会发现输入缓存不为空了。然后x,y,z就会分别读入数据了。x='a' ,y ='b', z= 'c'; 注意,此时程序的输入缓存中的数据并没完 即”de" 还在缓存里。
程序继续运行到某处的输入语句cin>>u>>v >>w; (也为char类型) ,然后发现输入缓存中还有数据,则u = 'd' ,v = 'e'; 但将给w赋值的时候发现没数据了,此同就同上了,程序又开始等待 (同上) .
验证程序(c++):
int main() { char x,y,z,u,v,w; cout<<"Please enter the data :"; cin>>x>>y>>z; cout<<"then x = "<<x<<",y = "<<y<<",z = "<<z<<endl; //再次输入u,v,w cin>>u>>v>>w; cout<<"u = "<<u<<" , v = "<<v<<" , w = "<<w<<endl; return 0; }
第一次输入abcde
第二次输入f
输出结果:x='a',y='b',z='c',u='d',v='e',w='f'
再来看看输入类型不相符时的情况:
再此之前,先来简单说下cin这个istream类的个人理解。
cin为输入流对象,在iostream头文件中.
这个cin对象,里面有个标志位成员变量flag(假设)是用来指示cin是否遇到过错误(0为error, 1 为OK)。比如:cin>>x; (x为int型) , 但是我们确输入的是字母. 这时候cin的那个错误标志就会被置为false(即遇到错误) 。 此标志位被置为false后,就代表cin对象遇到错误了,这个位不会自动恢复正常。 然后后面的输入语句cin>>y等等,就都会直接结束了。而不会阻塞等待用户输入了。 直接结束的意思是后面的输入无效(但程序并不会中止),比如上面的y 就不变,相当于没有执行cin操作一样.
要使cin从错误变为正常可以用 cin.clear()语句清除错误.
大家应该见过此类的表达式
if(cin) 或者while(cin)
//do process
这个表达式是什么意思呢? cin本来是一个istream对象呀,如何用非bool来来作测试条件呀? 这里cin的实现里应该重载了一个(bool)cin强制转换为bool量,那这个强制转换成啥呀? 即上面的标志位flag了, 若flag为真,则此条件也为真,若为假,则此条件也就为假了.
下面看个具体的例子:
当为语句int x; 程序中有条输入语句cin>>x; 我们来看看情况会如何?
程序运行的流程还是会一样,先检测输入缓存,若为空,则检测EOF标志。若无EOF标志,则等待输入。
当程序运行到cin>>x时,我们输入了一个字符a,再按下回车。输入缓存中就为 'a'了。
程序检测输入缓存,发现不为空。然后就读依到字符'a'了。但是发现a不是数字呀!! 此时cin的标志位就会置为false,即遇到错误。
但是现在的输入缓存中会变成什么样呢? 程序发现'a'不是数字后,会将其再次放到输入缓存中.即输入缓存还是为'a';
验证程序如下:
int main() { int x = 0; cout<<"enter a data for int x:"; cin>>x; cout<<x<<endl; char c = 'p'; cout<<"cin的标志位:"<<(bool)cin<<endl; //重载的bool强制转换,可以试试(int)cin等发现编译错误。 cin>>c; cout<<"c = "<<c<<endl; //有变化吗?c并未改变 cin.clear(); //清除cin的错 cout<<"cin的标志位:"<<(bool)cin<<endl; cin>>c; cout<<"c = "<<c<<endl; //现在成功输入了吗? }
再来看看while(cin>>x)结束的方式 (x为任意类型)
1.可以用 上面的方法,使cin的标志位置为false.但这种方法得在while后面再用cin前,使用cin.clear()清除错误。 (cin>>x的返回值为cin的引用.相当于cin>>x,while(cin){})
2.可以在输入新的一行时输入^z (键盘上按下 ctrl+z) 回车,这种情况下cin也标志位也会置为false. 注意:^z得出现在输入的每行的第一个才有效!
下面就我个人理解来解释下 ^z:
^z 相当于文件输入流的EOF标志。
从上面可知cin>>x的时候,程序是先检测输入缓存是否为空。若为空,则再检测EOF标志。若无EOF,则程序等待用户输入。注:^z并不会进入到输入缓存中
每按一次回车时候,程序就执行下上面的步骤。
我们可以认为 ^z 符号只在一次回车时有用。即当输入 'abc'^z的时候, 程序执行不到检测EOF时,就已经有输入了(此时这次的^z就已经失效了,因为它的前面有输入了)
故:^z ( ctrl+z)结束时,得在行首输入! 后面要再次使用cin时,得再调用cin.clear();
验证如下:
int main() { int c; while(cin>>c){ cout<<"in while"<<endl; cout<<"请在行首按下^z结束(ctrl+z) 或者输入字母结束 "<<endl; } cout<<"cin 的状态:"<<(bool)cin<<endl; //观察cin的状态 cin.clear();//然后就可以接着用cin了 }
本文完。如有错误,还请各个高手指正。
转载请注明出处.
相关文章推荐
- 个人理解,中断上半部,下半部,硬中断,软中断
- 对几个小问题的个人理解
- 个人对理想团队模式构建的设想及对软件流程的理解
- JQuery trigger 个人理解手记
- 地址空间的抽象理解(个人理解)
- android事件机制个人理解
- Spark RDD、DataSet、DataFrame--区别(个人理解)
- Static的个人理解
- 个人理解广度优先搜索
- while(cin)的理解
- 对研发经理这一岗位的个人理解
- 个人猜想的web安全——理解PHP的sessionID的实现
- 对Android为intent提供两种传递对象参数类型的方法的个人简单理解
- C#委托之个人理解
- RAM/ROM个人理解
- 开源软件版权盈利问题:个人理解
- 对JVM中垃圾回收机制的个人理解--对象的生命周期
- Ajax的个人理解
- 个人理解的ORM
- 深入理解Linux内核个人小结8---内存区管理