c++ 字符串切分split 的举例实现
一共给出了四种方式
1、 strtok
2、 stringstream
3、 字符串查找
4、 基于封装的方式,提供了 c++11 foreach 接口
代码
vector<string> split(string s) {
vector<string> res;
const char *p = strtok((char *) s.c_str(), " ");
res.push_back(p);
while ((p = strtok(NULL, " "))) {
res.push_back(p);
}
return res;
}
vector<string> split2(string s) {
vector<string> res;
stringstream ss(s);
string tmp;
while (ss >> tmp) {
res.push_back(tmp);
}
return res;
}
vector<string> split3(string s) {
vector<string> res;
auto start = s.find_first_not_of(" ", 0);
auto pos = s.find_first_of(" ", start);
while (string::npos != start) {
res.push_back(s.substr(start, pos - start));
start = s.find_first_not_of(" ", pos);
pos = s.find_first_of(" ", start);
}
return res;
}
class Splitor;
class SplitorIte {
private:
Splitor *sp;
string s;
public:
static string splitorIteNULL;
SplitorIte(Splitor *sp);
SplitorIte();
SplitorIte &operator++();
string operator*() {
return s;
}
bool operator!=(const SplitorIte &other) {
return s != other.s;
}
};
string SplitorIte::splitorIteNULL = "!!!!!!!";
class Splitor {
private:
string s;
unordered_set<char> des;
int start = 0;
bool allow_empty = false;
public:
Splitor(const string &s, string delim, bool allow_empty = false) : s(s), des(delim.begin(), delim.end()),
allow_empty(allow_empty) {}
auto operator()() -> string {
string res;
do {
int p = start;
// 如果当前就是
if (p >= s.size()) {
return SplitorIte::splitorIteNULL;
}
if (allow_empty && des.count(s[p])) {
start++;
return "";
}
// 找到第一个非
while (p < s.size() and des.count(s[p])) p++;
if (p == s.size()) {
return SplitorIte::splitorIteNULL;
}
// 找到第一个是
int q = p + 1;
while (q < s.size() and !des.count(s[q])) q++;
res = s.substr(p, q - p);
start = q + 1;
} while (!allow_empty && res.empty());
return res;
}
SplitorIte begin() {
return {this};
}
SplitorIte end() {
return {};
}
};
SplitorIte::SplitorIte(Splitor *sp) : sp(sp) {
s = (*sp)();
}
SplitorIte::SplitorIte() {
sp = nullptr;
s = splitorIteNULL;
}
SplitorIte &SplitorIte::operator++() {
s = (*sp)();
return *this;
};
int main() {
cout << "允许出现空格:\n";
string s = "a ssst";
Splitor sp(s, "s", true);
int i = 0;
for (auto str: sp) {
cout << i << "\t[" << str << "]" << endl;
i++;
}
cout << "不允许出现空格:\n";
Splitor esp(s, "s");
i = 0;
for (auto str: esp) {
cout << i << "\t[" << str << "]" << endl;
i++;
}
}