cin
cin>>
cout<<
像是水从上往下流。
cin可以连续从键盘读取想要的数据,以空格、tab或换行作为分隔符。
cin遇到分隔符(可以是换行符等默认的,也可以是自定义的诸如逗号)即停止,但不删除分隔符,如果继续读取仍会读到分隔符。不过cin对每次读取时读到的前置换行符、tab和空格会忽略(遇到分隔符算完成一次读取)。
不想略过空白字符,那就使用 noskipws 流控制。比如cin>>noskipws>>input;
cin可读取字符串。
cin.get
cin.get不会忽略前置的空格、tab和换行符,并会把分隔符留在输入缓冲区。为了删除分隔符,可以为此加一句cin.get(),括号内可以不写东西。
cin.get(char var)如果成功返回的是cin对象,因此可以支持链式操作,如cin.get(b).get()。
cin.get读取单个字符
char a;
cin.get(a);
cin.get读取一行
读取一行可以使用istream& get ( char* s, streamsize n )或者istream& get ( char* s, size_t n, streamsize delim )。二者的区别是前者默认以换行符结束,后者可指定结束符。n表示目标空间的大小。
char array[20] = { NULL };
cin.get(array,20,';');
读取一行时,第二个参数n不可缺省。第三个参数可缺省,缺省时默认以换行符结束,也可以指定分隔符。
若在达到n或遇到分隔符之前的字符串超过了变量数组的长度-1,则调试会报错。n应不大于变量数组的长度-1。
cin.getline
cin.getline遇到分隔符停止且会删掉缓冲区的分隔符。
char array[20] = { NULL };
cin.getline(a, 20); //默认以换行符结束
cin.getline(a, 20, ',');
读取一行时,第二个参数n不可缺省。第三个参数可缺省,缺省时默认以换行符结束,也可以指定分隔符。
若在达到n或遇到分隔符之前的字符串超过了变量数组的长度-1,则调试会报错。n应不大于变量数组的长度-1。
cin清除错误信息并清空缓冲区
输入时,可能一行没读完就因为超过了待输入字符数组的长度而发生阶段。此时cin的错误标志位会被置0,且因为这一行还有残余在输入缓冲区的部分,无法正常读取下一行。此时需要清空错误标志位,并清空缓冲区。
cin.clear(); // 清除错误标志
cin.ignore(numeric_limits<std::streamsize>::max(),'\n'); //清除缓冲区的当前行
详细叙述如下:
清楚错误信息
使用cin读取键盘输入时,难免发生错误,一旦出错,cin将设置条件状态(condition state)。条件状态标识符号为:
goodbit:无错误
eofbit:已到达文件尾
failbit:非致命的输入/输出错误,可挽回
badbit:致命的输入/输出错误,无法挽回
若在输入输出类里.需要加iOS::标识符号。与这些条件状态对应的就是设置、读取和判断条件状态的流对象的成员函数。他们主要有:
s.eof():若流s的eofbit置位,则返回true;
s.fail():若流s的failbit置位,则返回true;
s.bad():若流s的badbit置位,则返回true;
s.good():若流s的goodbit置位,则返回true;
s.clear(flags):清空状态标志位,并将给定的标志位flags置为1,返回void。
s.setstate(flags):根据给定的flags条件状态标志位,将流s中对应的条件状态位置为1,返回void。
s.rdstate():返回流s的当前条件状态,返回值类型为strm::iostate。strm::iostate 机器相关的整形名,由各个iostream类定义,用于定义条件状态。
了解以上关于输入流的条件状态与相关操作函数,下面看一个因输入缓冲区未读取完造成的条件状态位failbit被置位,再通过clear()复位的例子。
#include <iostream>
using namespace std;
int main()
{
char ch, str[20];
cin.getline(str, 5);
cout<<"flag1:"<<cin.good()<<endl; // 查看goodbit状态,即是否有异常
cin.clear(); // 清除错误标志
cout<<"flag1:"<<cin.good()<<endl; // 清除标志后再查看异常状态
cin>>ch;
cout<<"str:"<<str<<endl;
cout<<"ch :"<<ch<<endl;
system("pause");
return 0;
}
输入:12345[回车],输出结果为:
可以看出,因输入缓冲区未读取完造成输入异常,通过clear()可以清除输入流对象cin的异常状态。,不影响后面的cin>>ch从输入缓冲区读取数据。因为cin.getline读取之后,输入缓冲区中残留的字符串是:5[换行],所以cin>>ch将5读取并存入ch,打印输入并输出5。
如果将clear()注释,cin>>ch;将读取失败,ch为空。
cin.clear()等同于cin.clear(ios::goodbit);因为cin.clear()的默认参数是ios::goodbit,所以不需显示传递,故而你最常看到的就是:
cin.clear()。
清空输入缓冲区
们想到了在进行输入时,对输入缓冲区进行清空和状态条件的复位。条件状态的复位使用clear(),清空输入缓冲区应该使用:
函数原型:istream &ignore( streamsize num=1, int delim=EOF );
函数作用:跳过输入流中n个字符,或在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)。
使用示例如下
#include <iostream>
using namespace std;
int main()
{
char str1[20]={NULL},str2[20]={NULL};
cin.getline(str1,5);
cin.clear(); // 清除错误标志
cin.ignore(numeric_limits<std::streamsize>::max(),'\n'); //清除缓冲区的当前行
cin.getline(str2,20);
cout<<"str1:"<<str1<<endl;
cout<<"str2:"<<str2<<endl;
system("pause");
return 0;
}
程序输入:12345[回车]success[回车],程序输出:
注意:
(1)程序中使用cin.ignore清空了输入缓冲区的当前行,使上次的输入残留下的数据没有影响到下一次的输入,这就是ignore()函数的主要作用。其中,numeric_limits::max()不过是头文件定义的流使用的最大值,你也可以用一个足够大的整数代替它。
如果想清空输入缓冲区,去掉换行符,使用:
cin.ignore(numeric_limits< std::streamsize>::max()); 清除cin里所有内容。
(2)cin.ignore();当输入缓冲区没有数据时,也会阻塞等待数据的到来。
(3)有个疑问,网上很多资料说调用cin.sync()即可清空输入缓冲区,本人测试了一下,VC++可以,但是在linux下使用GNU C++却不行,无奈之下,linux下就选择了cin.ignore()。