cin是C++中的IO库中的istream类的一个实例对象,用以从标准输入流中读取数据。定义于
常用的cin用法有cin >>、cin.get()、cin.getline()。
cin >> 可以连续读取多个输入,只要输入之间使用空格或tab等空白符分隔就可以。需要注意的是,cin >> 会将回车符丢弃,即输入的字符串中不会包含回车符。
float a, b;
char c;
// cin可以应对不同类型的输入
cin >> a >> b >> c;
合法的输入应该为:
1.1 3.14 b
cin.get()在istream类中被重载过,因此,它既可以用来获取一个字符输入,同时也可以用来获取一行输入。
读取一个字符的版本:
char a, b;
// 如下所示,读取一个字符的cin.get()也被重载过
// 版本一
a = cin.get(); // 函数原型 int get();
// 版本二
cin.get(b); // 函数原型 istream & get(char &);
// 不同于版本一,版本二返回的是istream的引用,因此可以进行串联输入
cin.get(a).get(b).get(...);
读取一行字符串的版本:
#include
using namespace std;
int main() {
char str1[10];
char str2[10];
// 函数原型:istream & get(char *, size_t);
cin.get(str1, 5);
// cin.clear();
// 函数原型:istream & get(char *, size_t, char);
cin.get(str2, 9, '$');
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}
上述函数原型中char * 表示要输入的对象,size_t表示最大输入的字符数,第二个函数原型中的char表示结束输入字符,默认以’\n’结束输入。
为了确保向目标内存中输入的是一个字符串,因此cin在向字符数组中输入时,编译期将预留出一个位置存放’\0’字符。因此,在上述代码中,虽然使用的是cin.get(str1, 5),但实际只读取了四个字符。而后的o和换行符’\n’就被作为下一个cin.get()的输入。对于上述的理论,我们可以将上述代码改为cin.get(str1, 1);进行测试,不过需要注意的是,未获取到字符输入时,cin将设置failbit位,要使用cin.clear()将其复位,才能继续获取下一个输入。
需要注意的是,使用cin.get()获取一行输入时会将残余的’\n’滞留在缓冲区中,会阻塞缓冲区。因此平常获取多行输入时,需要使用额外的cin.get()将额外的’\n’去除。
#include
using namespace std;
int main() {
char str1[10];
char str2[10];
cin.get(str1, 10);
// cin.get();
cin.get(str2, 10);
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}
cin.getline()也可以用于获取一行输入,其用法与cin.get()相似
#include
using namespace std;
int main() {
char str1[10];
char str2[10];
// 函数原型: istream & getline(char *, size_t);
cin.getline(str1, 5);
// cin.clear();
// 函数原型: istream & getline(char *, size_t, char);
cin.getline(str2, 8, '$');
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}
不同于cin.get()函数,cin.getline()在输入完成后,如果该行中还有剩余字符,将设置cin的failbit位,这里使用cin.clear()复原。
还有不同于cin.get()的一点是,获取一行输入后,cin.getlin()会将缓冲区中剩余的回车符去除,因此不用使用cin.get()将额外的’\n’去除。
#include
using namespace std;
int main() {
char str1[10];
char str2[10];
// 函数原型: istream & getline(char *, size_t);
cin.getline(str1, 10);
// 函数原型: istream & getline(char *, size_t, char);
cin.getline(str2, 10, '$');
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}
使用cin操作输入流时,难免会发生错误。但有些错误是可以修正的,有些错误则是系统级错误,不可挽回。
下面是一些cin的状态标识:
cin还提供了与这些状态对应的成员函数,用来设置、读取、判断条件状态成员。
#include
using namespace std;
void showcinstate(istream & is) {
cout << "cin's state: " << endl
<< "eofbit: " << boolalpha << is.eof() << endl
<< "failbit: " << is.fail() << endl
<< "badbit: " << is.bad() << endl
<< "good: " << is.good() << endl;
}
int main() {
int i;
istream::iostate flags = cin.rdstate();
showcinstate(cin);
cout << endl;
// 这里故意进行错误的输入
cin >> i;
showcinstate(cin);
cout << endl;
// 复位failbit和goodbit,保持其他标志位不变
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.goodbit);
// 这里也可以使用cin.clear()复位所有位
showcinstate(cin);
cout << endl;
// 使用cin.setstate()设置指定的状态标志位
auto bit = ~cin.failbit;
cin.setstate(ios::failbit);
cin.setstate(ios::eofbit);
showcinstate(cin);
return 0;
}
上述输入函数中,除了cin >> 以外,其余函数都只能针对c风格字符串进行输入,但其实标准库还定义了getline()全局函数可以用来对string进行输入。
#include
#include
using namespace std;
int main() {
string str1;
string str2;
// 函数原型: istream& getline ( istream& is, string& str);
getline(cin, str1);
// 函数原型: istream& getline ( istream& is, string& str, char delim);
getline(cin, str2, '*');
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}