c++11 string转ing_C++ 的 string 为什么不提供 split 函数?

C++11以前有很多原因不能提供一个通用的split,比如说需要考虑split以后的结果存储在什么类型的容器中,可以是vector、list等等包括自定义容器,很难提供一个通用的;再比如说需要split的源字符串很大的时候运算的时间可能会很长,所以这个split最好是lazy的,每次只返回一条结果。

C++11之前只能自己写,我目前发现的史上最优雅的一个实现是这样的:

void split(const string& s, vector& tokens, const string& delimiters = " ")

{

string::size_type lastPos = s.find_first_not_of(delimiters, 0);

string::size_type pos = s.find_first_of(delimiters, lastPos);

while (string::npos != pos || string::npos != lastPos) {

tokens.push_back(s.substr(lastPos, pos - lastPos));//use emplace_back after C++11 lastPos = s.find_first_not_of(delimiters, pos);

pos = s.find_first_of(delimiters, lastPos);

}

}

从C++11开始,标准库中提供了regex,regex用来做split就是小儿科了,比如:

std::string text = "Quick brown fox.";

std::regex ws_re("\\s+"); // whitespacestd::vector<:string> v(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),

std::sregex_token_iterator());

for(auto&& s: v)

std::cout<

C++17提供的string_view可以加速上面提到的第一个split实现,减少拷贝,性能有不小提升,参看此文:Speeding Up string_view String Split Implementation。

从C++20开始,标准库中提供了ranges,有专门的split view,只要写str | split(' ')就可以切分字符串,如果要将结果搜集到vector中,可以这样用(随手写的,可能不是最简):

string str("hello world test split");

auto sv = str

| ranges::views::split(' ')

| ranges::views::transform([](auto&& i){

return i | ranges::to(); })

| ranges::to();

for(auto&& s: sv) {

cout<

}

其实C语言里面也有一个函数strtok用于char*的split,例如:

#include #include #include using namespace std;

int main()

{

string str = "one two three four five";

char *token = strtok(str.data(), " ");// non-const data() needs c++17 while (token != NULL) {

std::cout << token << '\n';

token = strtok(NULL, " ");

}

}

//如你所愿,输出如下:one

two

three

four

five

这里要注意的是strtok的第一个参数类型是char*而不是const char*,实际上strtok的确会改变输入的字符串。

参考文献:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值