一、cin和getline同时使用易错点
当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取。
在使用getline读入一整行时,若是前面是使用getchar()、cin这类读入了一个字母,但是不会读入后续换行’\n’符号或者空格的输入时,再接getline()就容易出现问题。比如:
/* 输入 :
1
one
*/
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
int num;
cin>>num;// 读取了1,但是回车还留在数据流中
// 如果没有下面这句话,str得不到准确的输入
// str 输出为空
cin.ignore();
string str;
getline(cin,str);
cout << str.size() << endl;
return 0;
}
这是因为输入数字之后,敲回车,产生的换行符仍然滞留在输入流了,接着就被getline(cin,s)给读进去了,此时的s=’\n’,所以实际上s只是读入了一个换行符’\n’。
二、读取以空格分割的数据
1.使用cin
// 读取以空格为分割的一行数据
/* 输入 :
1 2 3 4
输出 :
1 2 3 4
*/
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
int num;
vector<int> nums;
while(cin >> num){// 遇到回车就停止输入
nums.push_back(num);
if(getchar()=='\n') break;//只能放这里,不然会少了最后一个输入值
}
for(auto v : nums){
cout<<v<<" ";
}
cout<<endl;
return 0;
}
2.使用istringstream
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string str;
getline(cin,str);
istringstream in_str(str);
vector<int> nums;
int num;
while(in_str>>num){
nums.push_back(num);
}
for(auto v : nums){
cout<<v<<" ";
}
cout<<endl;
return 0;
}
三、读取以逗号分割的数据
// 读取以,分割的一行数据
// 输入: 1,2,3,4,5
// 输出 1 2 3 4 5
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
string str;
getline(cin,str);
stringstream ss(str);
vector<int> nums;
char del = ',';// 分割符号为,
string tmp;
while (getline(ss, tmp, del)) {
nums.push_back(stoi(tmp));
}
// 输出 1 2 3 4 5
for(auto v : nums){
cout<<v<<" ";
}
}
那么可以写出分割以逗号为分割符的字符串提取函数:
// str 为输入字符串,del为分隔符,返回分割之后的字符串数组
vector<string> split(string str, char del) {
stringstream ss(str);
string tmp;
vector<string> res;
while (getline(ss, tmp, del)) {
res.push_back(tmp);
}
return res;
}