本文介绍了cin重载的operator>>()函数、get()函数、getline()函数以及相应的eofbit和failbit问题。
cin重载了operator>>()函数来实现对任何类型数据的输入操作,重载的类型如下:
int& short& long& unsigned int& unsigned short& unsigned long& float& double&
long double& char& signed char& unsigned char& char* signed char* unsigend char*
这里有必要说明一下字符串的输入,如:
char str[10];
cin>>str;
此时cin对象就会调用函数istream &operator>>(char*),该函数读取用户输入的每一个字符,并通过指针将它们放置到指针所指向地址的内
存中,最后添加一个空字符作为字符串结束符。比如我们输入hello,那么operator>>(char*)函数就会将hello 存放到数组str中
另外,cin也可以与hex、oct、dec等格式符一起合用
#include <iostream> using namespace std; int main() { int x; cin>>hex>>x; //设置输入模式为十六进制(16) cout<<x<<endl; //因为没有输出模式,因此按照默认的十进制来输出(22) return 0; }
istream::get的几种形式
形式一:
int get() 接受单个字符并返回该字符的ASCII码
istream &get(char& c) 接受单个字符并将其存放到字符c中
形式二:
istream get(char* s, streamsize n)
istream get(char* s, streamsize n, char delim) 读取流中的字符,直到碰到结束字符delim(默认为'
'),或者n-1个字符已经被
读取,另外,一个空字符' '会被自动添加到s中作为字符串结束符
注:
1.如果碰到结束符,则结束符并不会被读取,而是同剩余字符一起继续留在缓冲区中
2.如果读取到EOF,函数结束,eofbit和failbit都会被设置为1
3.需要注意的是,当文件指针指向文件末尾时,并不会置eofbit为1,此时eofbit仍为0,只有尝试读取文件结束位置时(即等到下一次读取时)
,才会置eofbit为1,同时failbit也被置为1,此时会打印出无用的结束符(int型值为-1,即EOF)或者重复前一字符
//get() #include <iostream> using namespace std; int main() { char a[5]; cin.get(a,5); //输入"hello回车",由于输入字符超过设定的字符数目长度,因此程序只会读取"hell",自动添加' '赋给 //数组a,因此剩下的"o回车"保留在缓冲区 cout<<a<<endl; //hell cout<<cin.fail()<<endl; //由于cin.get()不会设置failbit标志位,因此输出0 //cin.clear(); //由于failbit标志位没有被设置,且其他标志位也没有被设置,因此无需清除状态标志位 char ch; cin.get(ch); //由于输入缓冲区中的数据为"o回车",因此读取'o'赋给ch cout<<(int)ch<<endl; //111(o的ASCII码值) cin.get(ch); //继续读取"回车"赋给ch cout<<(int)ch; //10( 的ASCII码值) return 0; }
istream::getline的几种形式
istream& getline(char* s,streamsize n);
istream& getline(char* s,streamsize n,char delim);
读取流中的字符,直到读取的字符是结束字符delim(默认为'
'),或者n个字符已经被写入到s中(包括空字符' ',即其实只有n-1个字符被
读取并写入到s中),另外,一个空字符' '会被自动添加到s中作为字符串结束符(即第n个字符)
注:
1.当碰到结束字符时,结束字符会被读取并丢弃,不会被写入到s中
2.当读取EOF时,函数结束,eofbit和failbit都被设置为1
3.当没有可读取的字符或者n个字符中没有结束字符delim时,failbit被设置为1。需要注意的是如果streamsize为n,且第n个字符恰好是结束
字符delim,则该字符会被读取并丢弃,同时failbit不会被设置为1
可以看到,get()与getline()的区别在于,
1.(读取n-1个字符后)如果碰到delim,get()函数不会读取delim,而是将其继续留在缓冲区中;而getline()函数则读取delim,并将其丢弃
2.如果n个字符中没有结束字符delim时,get()并不会将failbit设置为1,而getliine()会将failbit设置为1
#include <iostream> using namespace std; int main() { char a[5]; cin.getline(a,5); //输入"hello回车",由于输入字符超过设定的字符数目长度,因此failbit被设置为1,程序只会读取"hell", //并自动添加' '赋给数组a,因此剩下的"o回车"保留在缓冲区 cout<<a<<endl; //hell cout<<cin.fail()<<endl; //1 cin.clear(); //清除状态标志位,即将failbit重置 char ch; cin.get(ch); //由于输入缓冲区中的数据为"o回车",因此读取'o'赋给ch cout<<ch<<endl; //o cin.get(ch); //继续读取"回车"赋给ch cout<<(int)ch; //10 return 0; }
//如果streamsize为n,且第n个字符恰好是结束字符delim,则该字符会被读取并丢弃,同时failbit不会被设置为1 #include <iostream> using namespace std; int main() { char a[5]; cin.getline(a,5); //输入"word回车",程序读取"word回车",发现第n个恰好是delim,因此回车被丢弃,并自动添加' '赋给 //数组a。此时,缓冲区为空 cout<<a<<endl; //word cout<<cin.fail()<<endl; //0 char ch; cin.get(ch); //输入"2回车",读取'2'赋给ch cout<<ch<<endl; //2 cin.get(ch); //继续读取"回车"赋给ch cout<<(int)ch; //10 return 0; }