隐藏在cin中的陷阱

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议.

在C++中有很多时候会栽在cin缓存区这个坑里,特别是将输入作为循环判断条件的时候,输入错误的情况下往往会陷入死循环。例:

1
2
3
4
5
int i;
while (1) {
cout << "输入数字";
cin >> i;
}

想要达到的效果是循环输入数字,一旦输入错误,比如输入为一个字母的时候,往往会陷入到一个死循环中。

不停的输出提示信息,但是不允许用户再次输入。

查了一下发现,

这个是因为cin缓冲区没有清理,cin以后的每一次一次循环时直接读取缓冲区了

因此,在输入前加上清空输入缓冲区的语句就可以解决问题。c++用于清空输入缓存的函数有三个:cin.clear(),cin.sync(),cin.ignore()。

cin.clear()是用来更改cin的状态标示符的,cin在接收到错误的输入的时候,会设置状态位good。如果good位不为1,则cin不接受输入,直接跳过。如果下次输入前状态位没有改变那么即使清除了缓冲区数据流也无法输入。所以清除缓冲区之前必须要cin.clear()。

cin.ignore(a,ch):从输入缓冲去中提取字符,提取的字符被忽略,不被使用。每抛弃一个字符,它都要计数和比较字符,如果计数值达到a或者被忽略的字符是ch,则cin.ignore()函数终止执行。默认参数是a=1,即仅忽略缓冲区中的第一个字符。它的一个常用功能是用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响。比如cin.ignore(1024,’\n’),通常把第一个参数设置得足够大,这样实际上总是只有第二个参数起作用,所以这一句就是把回车(包括回车)之前的所有字符从输入缓冲区中清除。

cin.sync()的作用是清除输入缓冲区全部的内容。

所以加上在下一次输入前加上两行,清除错误缓存区即可。

1
2
3
4
5
6
7
int i;
while (1) {
cout << "输入数字";
cin >> i;
cin.clear();
cin.ignore();
}

不知道为什么我使用cin.sync()并不能清除输入缓冲区全部的内容,还是会出现死循环。

所以用cin.clear();cin.ignore();

cin这个缓存区清理在循环中是一个不可忽略的陷阱,

不中招也很难了解到,所以

every built ,every debug.

debug again ,better again.

坚持原创技术分享,您的支持将鼓励我继续创作!