split函数的实现
2013年1月17日 2 条评论前几天朋友问我要几道C++面试题,我说你让他先写一个string的split函数吧,类似C语言里的strtok. 现在想想自己的代码里,split函数的实现真是兴之所至,想到用什么方法就用什么方法:
一种方法是用stringstream,然后用getline:
void split(const std::string &s, char delim, std::vector<std::string> &elems) { std::stringstream ss(s); std::string item; while(std::getline(ss, item, delim)) { elems.push_back(item); } }也可以用regex实现:
void split(const string &s,const string &delim,vector<string>&elems){ regex reg(delim); sregex_token_iterator it(s.begin(),s.end(),reg,-1); sregex_token_iterator end; while (it!=end) { elems.push_back(*it++); } }然后去stackoverflow上search了一把,这个问题竟然在上面C++ tag问题中名列前茅!
支持各种定制的template实现:
template < class ContainerT > void tokenize(const std::string& str, ContainerT& tokens, const std::string& delimiters = " ", const bool trimEmpty = false) { std::string::size_type pos, lastPos = 0; while(true) { pos = str.find_first_of(delimiters, lastPos); if(pos == std::string::npos) { pos = str.length(); if(pos != lastPos || !trimEmpty) tokens.push_back(ContainerT::value_type(str.data()+lastPos, (ContainerT::value_type::size_type)pos-lastPos )); break; } else { if(pos != lastPos || !trimEmpty) tokens.push_back(ContainerT::value_type(str.data()+lastPos, (ContainerT::value_type::size_type)pos-lastPos )); } lastPos = pos + 1; } };使用string提供的find of函数实现:
void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ") { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } }如果是用空格分离,还有更简洁的方法:
void split(const string &s,const string &delim,vector<string>&elems){ string buf; stringstream ss(s); while (ss >> buf) elems.push_back(buf); }
split函数的实现
前几天朋友问我要几道C++面试题,我说你让他先写一个string的split函数吧,类似C语言里的strtok. 现在想想自己的代码里,split函数的实现真是兴之所至,想到用什么方法就用什么方法:
一种方法是用stringstream,然后用getline:
void split(const std::string &s, char delim, std::vector<std::string> &elems) { std::stringstream ss(s); std::string item; while(std::getline(ss, item, delim)) { elems.push_back(item); } }也可以用regex实现:
void split(const string &s,const string &delim,vector<string>&elems){ regex reg(delim); sregex_token_iterator it(s.begin(),s.end(),reg,-1); sregex_token_iterator end; while (it!=end) { elems.push_back(*it++); } }然后去stackoverflow上search了一把,这个问题竟然在上面C++ tag问题中名列前茅!
支持各种定制的template实现:
template < class ContainerT > void tokenize(const std::string& str, ContainerT& tokens, const std::string& delimiters = " ", const bool trimEmpty = false) { std::string::size_type pos, lastPos = 0; while(true) { pos = str.find_first_of(delimiters, lastPos); if(pos == std::string::npos) { pos = str.length(); if(pos != lastPos || !trimEmpty) tokens.push_back(ContainerT::value_type(str.data()+lastPos, (ContainerT::value_type::size_type)pos-lastPos )); break; } else { if(pos != lastPos || !trimEmpty) tokens.push_back(ContainerT::value_type(str.data()+lastPos, (ContainerT::value_type::size_type)pos-lastPos )); } lastPos = pos + 1; } };使用string提供的find of函数实现:
void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ") { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } }如果是用空格分离,还有更简洁的方法:
void split(const string &s,const string &delim,vector<string>&elems){ string buf; stringstream ss(s); while (ss >> buf) elems.push_back(buf); }