您的位置:首页 > 编程语言 > C语言/C++

C++程序学习--cin.get()函数读取空行时的细节

2016-11-13 19:17 393 查看
在学习《C++ Primer Plus》第六版第17章P785页的程序时遇到一个小问题,这个问题困扰了我很久,直到我找到了一篇博文http://www.cnblogs.com/tonglingliangyong/p/3908463.html,该问题是:

请看下面这个代码:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char str[20];
int  num;
cout << "请输入:\n";
cin.get(str, sizeof(str));
cout << "str: " << str << endl;

cout << "请输入一个数:";
cin >> num;
cout << "num = " << num << endl;

return 0;
}


上述代码非常简单,但是存在一个Bug,就是如果我们在输入 str 的时候特意输入一个空行时,就会使num无法输入了,get()函数在读到空行的时候,会将换行符保留在输入队列,但同时会将cin的状态置为错误,并且如果此时代码中有while()循环时,cin的错误会一直持续,那样就会陷入死循环。我们可以用下面代码来捕获该错误:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
char str[20];
int  num;
cout << "请输入:\n";
cin.get(str, sizeof(str));

if(cin.rdstate() == ios::goodbit)
{
cout << "输入一行正确.\n";
cout << "str: " << str << endl;
}

if(cin.rdstate() == ios::failbit)
{
cout << "输入了空行、或者其他错误.\n";
cin.clear();
cin.sync();
}

cout << "请输入一个数:";
cin >> num;
cout << "num = " << num << endl;

return 0;
}
如果此时我们依然输入对str输入空行时,就会执行到failbit的条件中,代码中加入了:

cin.clear();
cin.sync();
这两句代码很重要,cin.clear()主要将cin的状态清0,让我们可以继续输入,cin.sync()让流与其对应的数据源同步,这样流就可以丢弃掉之前没有处理的数据,如果不这样做,前面的没有处理掉的数据如果不能转换为需要的类型,那么流会一直处于错误状态。

所以在使用get()函数需要读取空行时应该加入上面两条重要代码,如果我们将上面get()函数换成getline()函数时,对于 空行的处理则没有这麽多细节,getline()函数遇到换行符时会将换行符丢弃掉,即在下次输入中,输入队列不会有换行符存在,也不会产生cin的错误状态。

同时,上面两条代码的细节地方:

#include <iostream>
using namespace std;
int main()
{
int num1, num2;

cout << "请输入一个数:";
cin >> num1;
cout << "num1 = " << num1 << endl;
cin.clear(); cin.sync();
cin >> num2;
cout << "num2 = " << num2 << endl;
return 0;
}
我们特意输入abcd时,如果没有中间清空同步的两条代码,则后面的num2就不能再输入了...


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐