最近用python写多了爬虫,转回C++颇不适应,特别是字符串处理时需要的split,故存着,感觉还是挺经常用到的。
#include <sstream>
#include <iosteam>
#include <list>
using namespace std;
/*
* 使用string类的成员函数
* 因为要不断的插入且插入数量未知,所以返回值选择底层实现为双层链表的list
* 如果对分割后的结果有随机访问的需求,可以将list转换为vector,语句如下
* vector<string> tmp(ret.begin(), ret.end());
*/
void split(const string &s, const string &sep, list<string> &ret) {
unsigned int pos_start =0, pos=0;
while(true) {
pos = s.find(sep, pos_start);
if(-1==pos)
break;
ret.emplace_back(s.substr(pos_start, pos-pos_start));
pos_start = pos+1;
}
ret.emplace_back(s.substr(pos_start));
}
/*
* 可以再传入一个转换函数将分割出来的item转换成类型T
* 如果T是比较大的类的话,可以考虑自己修改成指针容器来存放和返回
*/
template <typename T>
list<T> split(const string &s, const string &sep, T (*translate)(const string &)) {
unsigned int pos_start =0, pos=0;
list<T> ret;
while(true) {
pos = s.find(sep, pos_start);
if(-1==pos)
break;
ret.emplace_back(translate(s.substr(pos_start, pos-pos_start)));
pos_start = pos+1;
}
ret.emplace_back(translate(s.substr(pos_start)));
return ret;
}
// for test
int string2int(const string &s) {
stringstream ss;
ss << s;
int ret;
ss >> ret;
return ret;
}
// for test
int main() {
string input = "23,45,67,89";
string sep = ",";
list<int> splits = split(input, sep, string2int);
for_each(splits.begin(), splits.end(), [](const int &item){cout << item << ends;});
}
/*
* 使用stringstream
*/
void split(const string &s, char sep, list<string> &ret) {
stringstream ss(s);
string item;
while(getline(ss, item, sep)) {
ret.emplace_back(item);
}
}