1、cin
1.1、cin变成死循环
死循环case1:在写学习《C++数据结构与算法》的时候,链表那一章有一个图书馆程序,假如输入错误之后(比如需要输入一个整数,却输入了一个字符)就陷入了死循环。下面是一个示例代码:
#include <iostream>
using namespace std;
int main(){
int a = 0;
while(true){
cin >> a;
cout << "~" << a << '~' << endl;
}
return 0;
}
运行该程序,输入
1
~1~
23 546
~23~
~546~
f
0
0
0
...陷入死循环,一直输出0
问题:为什么不让我输入了呢?答案来自cin的用法及清空缓冲区。
分析:
第一次输入——1+回车,则cin’将缓冲区里的1给a;此时缓冲区为空
第二次输入——23 546+回车,因为当缓冲区中有残留数据时,cin函数会直接去读取这些残留数据而不会请求键盘输入;所以,这时循环执行了两次;第一次cin将23给a,,第二次跳过中间空格,把546给a。此时缓冲区为空。而且,回车符也会被存入输入缓冲区中。
前面两次输入,都是合法输入。
第三次输入——f+回车,这时第一个字符为非法输入(需要的是int),这时会将0给a。本次循环后,缓冲区不为空,而是存了回车符。因此下一次循环,不会等待下一次输入,而是将缓冲区的回车符作为输入。这时依然是非法输入,a的结果还是0,并且会一直这样循环下去。
解决方法:
#include <iostream>
using namespace std;
int main(){
int a = 0;
while(true){
cin >> a;
cout << "~" << a << '~' << endl;
if(!cin.good()){ //cin.good()是状态位,非法输入时,其值为0
cout << "wrong input!" << endl; //由于是非法输入,因此输出提示信息
cin.clear(); //改变cin的状态位
cin.ignore(); //清空缓冲区--cin.sync()在linux也是这个作用,但在linux中似乎不起作用
}
}
return 0;
}
1.2 用cin来输入
参考:C++输入cin,cin.get(),cin.getline()详细比较及例子
下面只是简述,详细例子可以查看参考链接
1.2.1 cin
结束条件:[enter],[space],[tab]
处理方法:cin遇到缓冲区中的[enter],[space],[tab]会结束当前输入,并舍弃[enter],[space],[tab],继续下一项输入,当有连续[space],[enter,[tab]会全部舍弃。
1.2.2 cin.get
(1)一参数
用法:a = cin.get() 或者 cin.get(a)
结束条件:输入字符足够后回车
说明:这个是单字符的输入,用途是输入一个字符,把它的ASCALL码存入到a中
处理方法:与cin不同,cin.get()在缓冲区遇到[enter],[space],[tab]不会作为舍弃,而是继续留在缓冲区中
#include <iostream>
using namespace std;
main ()
{
char ch;
ch=cin.get(); //或者cin.get(ch);
cout<<ch<<endl;
}
(2)二参数
用法:cin.get(arrayname,size) 把字符输入到arrayname中,长度不超过size
注释:arrayname必须是char[]类型,即char数组类型,不可以为string类型;size是指输入长度,即允许输入的最大长度。
一般size’限制了输入的大小,接受字符串的长度可以扩展,最多扩展至size大小。
处理方法:假设把数据输入到 char a[arraylength],数组长度为arraylength。cin.get(a,size)—size,arraylength不同可以分为四类:
类1:输入串长<size,输入串长>arraylength,会自动扩张arrayname大小,使能保存所有数据
例1:char a[10];cin,get(a,20);
输入:123456789012[enter]
输出a数组:123456789012 可以发现,输入12个字符到a[10]中,系统自动扩充a[10],此时实际数组长为13(‘123456789012’\0’’)。但当计算sizeof(a)时,还是现实为10
类2:输入串长<size,输入串长<arraylength,把串全部输入,后面补‘\0’
例2:char a[10];cin.get(a,20);
输入:12345[enter]
输出:12345,此时数组内数据为‘12345‘\0’’
类3:输入串长>size,先截取size个字符,若还是大于arraylength,则输入前arraylength-1个字符,最后补充‘\0’
例3:char a[5];cin,get(a,10);
输入:123456789012[enter]
输出:123456789 先截取了9个字符变成‘123456789‘/0‘’,然后放入到a中,a自动扩张长度
类4:输入串长>size,先截取size个字符,若小于arraylength,则把截取串放入数组中,最后补充‘\0’
例4:char a[15],cin.get(a,10)
输入:123456789012[enter]
输出:123456789 此时数组内为‘123456789‘\0’’ 注意:前size-1有效,最后一个补‘\0’
综上:当吧大于数组长度的字符串放出char a[arraylength]中,系统自动扩张数组a的长度使a能放得下,但是这么做容易产生运行错误
(3)三参数
用法:cin.get(arrayname,size,s) 把数据输入到arrayname字符数组中,当到达长度size时结束或者遇到字符s时结束
注释:a必须是字符数组,即char a[]l类型,不可为string类型;size为最大的输入长度;s为控制,遇到s则当前输入结束缓存区里的s将被舍弃
3.cin.getline()基本用法
cin.getline()的用法和cin.get()用法大致相同,没有一参数用法,只有二参数,三参数两类
cin.gerline(arrayname,size)
cin.getline(arrayname,size,s)用法与cin.get()效果大致相同,但也有些区别
(1)cin.getline(arrayname,size)与cin.get(arrayname,size)的区别
cin.get(arrayname,size)当遇到[enter]时会结束目前输入,他不会删除缓冲区中的[enter]
cin.getline(arrayname,size)当遇到[enter]时会结束当前输入,但是会删除缓冲区中的[enter]
(2)cin.getline(arrayname,size,s)与cin.gei(arrayname,size,s)的区别
cin.getline(arrayname,size,s)当遇到s时会结束输入,并把s从缓冲区中删除
cin.get(arrayname,size,s)当遇到s时会结束输入,但不会删除缓冲区中的s
————————————————
版权声明:本文为优快云博主「Mac Jiang」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/a1015553840/article/details/50579396