笔者在使用C++刷题的初期,经常无法将用户输入存储到程序中的变量,根本原因是当时没有理解C++控制台输入的原理,为此特撰写本博客记录C++控制台输入的原理及经常用到的输入函数。
在控制台中输入一行字符后,按下回车键,这行字符被送入缓冲区,回车键'\r'被替换为换行键'\n',
cin>>temp :先声明一个具体类型的变量,然后从缓冲区中取出按'\0'、'\t'、'\n'分割的一个字符串(如果字符串头部有空格将忽略,如果字符串尾部有空格将保留在输入缓冲区中),并将该字符串转换为对应的类型,如果该字符串对应的类型与实现声明的类型不匹配,则会导致未定义的行为(例如,声明int temp,而输入字符串“1z2”),代码如下所示
int var = 0;
if(!(cin >> var)) {
cout << "Illegal input" << endl;
}
else {
cout << "Your enter: " << var << endl;
}
在输入不合法的字符串(未能转化为整数)时,将会执行第3行的代码,如果想从未定义的行为中恢复,则需经过2步
1)使用cin.clear清除错误
2)使用cin.ignore()从输入缓冲区中清除不正确的字符
代码如下所示
int var = 0;
if(!(cin >> var)) {
cout << "Illegal input" << endl;
cin.clear();
cin.ignore(10000, '\n'); // ignore at most 10000 chars in the input buffer beforing encoutering '\n'
}
else {
cout << "Your enter: " << var << endl;
}
使用cin.get()将输入缓冲区的一个字符赋给临时字符变量('\0'、'\t'、'\n'均不会被忽略)
char ch;
ch = cin.get(); // the first way
cin.get(ch); // the second way
对于C-风格的字符串,输入方式有3种
1)cin使用'\0'、'\t'、'\n'确定字符串的结束位置,且'\0'、'\t'、'\n'保留在输入缓冲区中,cin将读取的字符串放在数组中,并自动在结尾处加入'\0'
2)istream& get(char* s, streamsize n);将n-1个字符读取到字符数组s中,最后一个位置存储'\0',该函数在读取指定数量的字符或遇到'\n'(也可以设置为其他字符)停止读取
3)istream& getline(char* s, streamsize n);将n-1个字符读取到字符数组s中,最后一个位置存储'\0',该函数在读取指定数量的字符或遇到'\n'(也可以设置为其他字符)停止读取,该函数从输入缓冲区中取出结束字符并丢弃
char charArr[100];
cin >> charArr; // 第1种方式,在遇到'\0'、'\t'、'\n'结束读取
cin.get(charArr, 100); // 第2种方式,在此处按下回车键,'\n'会被留在缓冲区
cin.getline(charArr, 100); // 第3种方式,在此处按下回车键,'\n'会被丢弃
对于string类型的字符串,输入方式有2种
string str;
cin >> str; // read one word
getline(cin, str); // 在此处按下回车键,会丢弃'\n'