C和C++中都有基本的终端输入函数,但是有时候如果不清输入函数的性质可能会有意想不到的结果。
第一,在C和C++中有三个标准流(standard stream):标准输入(stdi),标准输出(stdo),标准错误(stderr)。我们日常接触比较多的是前面两个,尤其是标准输入,由于其中不同功能输入函数较多一不小心就有可能出错。
比如下面这个例子:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char name[10] = {};
int year = 0;
cout<<"enter year:"<<endl;
cin>>year;
cout<<"enter you name:"<<endl;
cin.get(name, 10);
cout<<"year is: "<<year<<' '<<"name is: "<<name<<endl;
return 0;
}
你认为结果会是什么?结果如下:
可以看到我们并没有来得及输入名字就直接弹出了结果。原因是在输入1993后“回车”,此时“回车”仍然停留在输入队列中,下一个cin.get()一发现“回车”就认为这是一个空行,结果给name赋值为空。
第二,C和C++中输入函数只认识以下结束标识:空白符(空格、制表、回车),文件结束符EOF。问题在于如果从终端输入,发起下一个处理的指令是回车,回车就有可能留在输入队列中从而影响下一次的输入。
在C语言和C++中都有相应的处理,C中使用gets()函数(读取字符串)可以将末尾的回车替换成空字符‘\0’,并且丢弃回车符。在C++中则是getline()函数。而C语言中的单字符处理函数getc()、getchar(),C++中的get()都不会丢弃回车。当然,这样是为了检查是否将一个字符串读取完(读到回车),还是只是到了字符数的限制而退出了读取。
第三,可以再次从输入队列中读取单个字符以处理回车符,这样就把回车符从输入队列中去除。
如下:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char name[10] = {};
int year = 0;
cout<<"enter year:"<<endl;
cin>>year;
cin.get();
cout<<"enter you name:"<<endl;
cin.get(name, 10);
cout<<"year is: "<<year<<' '<<"name is: "<<name<<endl;
return 0;
}
结果如下: