在cin后getline所遇到的问题
在C++中,使用cin读取数据后,再使用getline读字符串,就会遇到buffer没有清空的问题,具体如下
#include<iostream>
#include<string>
using namespace std;
void main()
{
int value;
cin >> value;
std::vector<std::string> text;
for (int i = 0; i < value; i++)
{
string s;
getline(cin, s);
text.push_back(s);
}
for (auto &it : text)
{
cout << it << endl;
}
}
输入
//3
//abc
//ab
输出
//
//abc
//ab
即本来还需要读入3行字符串,却只读了1行。
为什么?
仔细发现,是text的第一个元素是空字符串,而不是我们想要的abc.
其实这里是个new line ,即\n
或者是一个endl
。
原因是我们在
cin>>value;
我们这里做的操作是
- 键盘输入2
- 然后敲了个enter回车.
所以此时缓冲区的队列内容应该是
输入2 | 输入enter | … |
---|---|---|
2 | endl |
于是在下面执行getline
时,由于检查到缓冲区还有数据,会把endl
读出来。
解放办法
在cin后,根据需要多调用一次getline,清空缓冲区。
#include<iostream> #include<string> using namespace std; void main() { int value; cin >> value; string strtmp; getline(cin, strtmp); //strtmp 只是把缓存区清空,沒有其他的作用 std::vector<std::string> text; for (int i = 0; i < value; i++) { string s; getline(cin, s); text.push_back(s); } for (auto &it : text) { cout << it << endl; } }
调用
cin.ignore()
把缓冲区清空。#include<iostream> #include<string> using namespace std; void main() { int value; cin >> value; cin.ignore(); //调用默认ignore() std::vector<std::string> text; for (int i = 0; i < value; i++) { string s; getline(cin, s); text.push_back(s); } for (auto &it : text) { cout << it << endl; } }
上次调用的
cin.ignore()
默认版本,它的完整流程如下:清空缓冲区直到遇到以下条件之一:
- 清空1个字符。
- 读到endl。
对于情况多字符,于是可以使用
cin.ignore(1000,'\n')
:这句话表示ignore满足下面条件之一就会停止:
- 参数1指ignore清空 1000个字符;
- 参数2要求ignore清空直到遇到
\n
(换行标志)