背景
对于程序而言,从键盘键入至程序读入,期间会将内容暂存在一个缓冲区中。代码的输入语句会直接从缓冲区中读取内容,所以有时候出现奇奇怪怪的意想不到的状况的时候,就是因为缓冲区也许留存有上一次的残留数据,导致被“错误读入”。
而且有些函数是对空格,回车不感冒,如cin,而有些却能够读取回车符如cin.get。下面就争对这些情况做个实验:
cin
cin 读取程序代码后面的对应的变量类型
结束标志:空格或者回车
cin 在读入之前, 会主动清空缓冲区中残余的空格或者回车.
// 输入:【enter1】【2】【空格】【空格】【c】【enter2】
int main() {
int a;
char b;
cin >> a >> b; // enter2 被留在缓冲区
cout << a << b;
}
// 输出:
2 c
https://en.cppreference.com/w/cpp/io/cin
cin.getline()
先看一下函数定义:
getline 函数从一个输入流(input stream)读入字符,并append至 string
函数不断读入字符并 append 至 string,其结束条件为:
a) 输入流读到了一个文件的末尾。getline 设置 eofbit
b) 下一个读入的字符为 delim, 这种情况下读入 delim 之后就停止读入,且 delim 不会 append 至 string
c) string 长度已经到了 max_size
构造函数显示,getline 函数 传入的 input_stream 的引用。所以,返回传入的流引用本身
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str );
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
第一种用法就是 getline(input_stream, str) —— 此用法则默认 delim 是换行符
第二种是getline(input_stream, str, delim) —— 不断读入,除非遇到(a、b、c)情况
getline 函数不会主动清空缓冲区,即会读入 enter 空格。所以会出现读入“异常”的情况
比如:
// 测试输入1:【enter1】【5】【enter2】【7777】
int main()
{
int a;
cin >> a;
string str;
getline(cin, str);
cout << str; // 测试1:没有正确读入我们想要的 7777
}
// 输出1:
【enter】
原因就是输入的【enter2】残留在了输入缓冲区,而且默认delim是换行符
【enter2】被 getline 读入,结束输入
// 测试输入2: 【enter1】【5】【空格4444】【enter2】
// 输出2:
【空格4444】
【空格】不会被geline主动清空,所以依旧读入
// 测试3:【enter1】【5】【空格】【aaa】【enter2】【123x】
int main()
{
int a;
cin >> a;
string str;
getline(cin, str, 'x');
cout << str; // 测试1:没有正确读入我们想要的 7777
}
// 输出3
【空格aaa】【enter】【123】
我们主动添加了 delim='x' ,所以可继续读入 enter
解决getline的误读: cin>>std::ws
int a;
cin >> a;
string str;
cin >> std::ws; // 解决残留的空格换行符
getline(cin, str);
cout << str;
如 cppreference 建议的,添加上 cin>>std::ws 即可
https://en.cppreference.com/w/cpp/string/basic_string/getline
http://www.augustcouncil.com/~tgibson/tutorial/iotips.html
http://www.augustcouncil.com/~tgibson/tutorial/UnderstandingComplexExpressions.pdf