C++ 的 splitstring函数 为什么不提供 split 函数

2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2008年3月 Linux/Unix社区大版内专家分月排行榜第二
2012年9月 Linux/Unix社区大版内专家分月排行榜第三2007年6月 Linux/Unix社区大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本帖子已过去太久远了,不再提供回复功能。C++基础知识(5)
C++标准库里面没有字符分割函数split ,这可太不方便了,我已经遇到&3次如何对字符串快速分割这个问题了。列几个常用方法以备不时之需。
方法一:&利用STL自己实现split 函数(常用,简单,直观)
原型:&vector&string&&split(const string &s,&const
string &seperator);
输入一个字符串,一个分隔符字符串(可包含多个分隔符),返回一个字符串向量。这是我最喜欢的方法,因为它最直观,在平常也最常用。实现及测试代码如下
#include &vector&
#include &string&
#include &iostream&
using namespace
vector&string& split(const string &s, const string &seperator){
vector&string&
typedef string::size_type string_
string_size i = 0;
while(i != s.size()){
//找到字符串中首个不等于分隔符的字母;
int flag = 0;
while(i != s.size() && flag == 0){
for(string_size x = 0; x & seperator.size(); ++x)
  if(s[i] == seperator[x]){
  ++i;
  flag = 0;
   break;
//找到又一个分隔符,将两个分隔符之间的字符串取出;
string_size j =
while(j != s.size() && flag == 0){
for(string_size x = 0; x & seperator.size(); ++x)
  if(s[j] == seperator[x]){
  flag = 1;
   break;
if(flag == 0)
  ++j;
if(i != j){
result.push_back(s.substr(i, j-i));
int main(){
string s = &a,b*c*d,e&;
vector&string& v = split(s, &,*&); //可按多个字符来分隔;
for(vector&string&::size_type i = 0; i != v.size(); ++i)
cout && v[i] && & &;
//输出: a b c d
提供了一段更简洁高效的代码,实现如下:
void SplitString(const std::string& s, std::vector&std::string&& v, const std::string& c)
std::string::size_type pos1, pos2;
pos2 = s.find(c);
while(std::string::npos != pos2)
v.push_back(s.substr(pos1, pos2-pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
if(pos1 != s.length())
v.push_back(s.substr(pos1));
方法二:&用C语言中的strtok 函数来进行分割
原型:&&char *strtok(char *str, const&char
strtok函数包含在头文件&string.h&中,对于字符数组可以采用这种方法处理。当然也可以将字符数组转换成字符串之后再使用法一。测试代码如下
#include &string.h&
#include &stdio.h&
int main(){
char s[] = &a,b*c,d&;
const char *sep = &,*&; //可按多个字符来分割
p = strtok(s, sep);
printf(&%s &, p);
p = strtok(NULL, sep);
printf(&\n&);
//输出: a b c d
方法三:&boost库中包含了split 函数
boost库有很多方法来实现split,也包含了一个split函数,可以直接使用,非常实用而且强大,但是得自己下载boost库。使用代码如下
#include &boost/algorithm/string.hpp&
#include &iostream&
#include &string&
#include &vector&
using namespace
using namespace
void print( vector &string& & v )
for (size_t n = 0; n & v.size(); n++)
cout && &\&& && v[ n ] && &\&\n&;
int main()
string s = &a,b, c ,,e,f,&;
vector &string&
cout && &Original = \&& && s && &\&\n\n&;
cout && &Split on \',\' only\n&;
split( fields, s, is_any_of( &,& ) );
print( fields );
cout && &Split on \& ,\&\n&;
split( fields, s, is_any_of( & ,& ) );
print( fields );
cout && &Split on \& ,\& and elide delimiters\n&;
split( fields, s, is_any_of( & ,& ), token_compress_on );
print( fields );
输出结果如下:
Original = &a,b, c ,,e,f,&
Split on ',' only
Split on & ,&
Split on & ,& and elide delimiters
在C++中还有很多方法来实现split 函数,有个C++ split 专题,详细比较分析了几种实现方法(见下图)。链接见文末参考文献。&
#---------------------------------------------------------------------------------#
《Accelerated C++》 by Andrew Koenig, Barbara E. Moo.
&Split a string& from&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13246次
排名:千里之外
原创:57篇
转载:33篇
(3)(4)(6)(16)(17)(6)(5)(21)(9)(1)(1)(1)但愿这篇笔记能在不久后变成陈旧的,C++ 标准库 扩充上了split
C++标准库的string没有split方法,在java和C#中有的。
虽然标准库的string的方法:使用find_first_of、substr、循环也能实现split,但是有很多更简单的办法:
C++是兼容C的,能使用C语言的库函数。标准库没有split,但 &string.h&中却有个&&
。但是阅读过strtok的文档后,感到失望:
strtok会修改源字符串:会把每个token结尾的分隔符替换成'\0' (详情 请参考上面的文档,并调试文档中的例子程序),所以 不能直接 strtok( string.c_str() , & &) 或者&strtok( string.data() , & &) 或者 strtok( &string[0], “ ”)。
那就只好先把string复制成C语言字符串。
2、借助boost
#include &boost/algorithm/string.hpp& // or more specifically, &boost/algorithm/string/split.hpp&
std::vector&std::string& strs;
boost::split(strs, &string to split&, boost::is_any_of(&\t &));
历史上,很多功能boost都比标准库走在前面。
This is the &document, and also an .
3、借助字符串流
I/O 的功能比string的方法丰富多了,从一个输入流对象中split应该简单吧:std::getline 或者&std::basic_istream::getline。
而字符串能转为流对象——字符串流。#include &sstream&
这是一篇很好的 c++ split a string&&,很全很详细。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
使用中,效果不错哦:
访问:34531次
积分:1023
积分:1023
排名:千里之外
原创:51篇
转载:32篇
评论:10条
(3)(1)(2)(7)(4)(1)(1)(4)(1)(7)(1)(1)(5)(7)(4)(2)(5)(6)(6)(5)(1)(1)(5)(1)11686人阅读
C/C++(135)
toupper, tolower
地球人都知道 C++ 的 string 没有 toupper ,好在这不是个大问题,因为我们有 STL 算法:
#include &iostream&
#include &algorithm&
int main()
string str = &heLLo&;
transform(str.begin(), str.end(), str.begin(), toupper);
cout&&str.c_str()&&
transform(str.begin(), str.end(), str.begin(), tolower);
cout&&str.c_str()&&
当然,我知道很多人希望的是 s.to_upper() ,但是对于一个这么通用的 basic_string 来说,的确没办法把这些专有的方法放进来。如果你用 boost stringalgo ,那当然不在话下,你也就不需要读这篇文章了。
------------------------------------------------------------------------
我们还知道 string 没有 trim ,不过自力更生也不困难,比 toupper 来的还要简单:
#include &iostream&
int main()
string str = &
str.erase(0, str.find_first_not_of(& &));
cout&&str.c_str()&&
str.erase(str.find_last_not_of(& &)+1);
cout&&str.c_str()&&
注意由于 find_first_not_of 和 find_last_not_of 都可以接受字符串,这个时候它们寻找该字符串中所有字符的 absence ,所以你可以一次 trim 掉多种字符。
-----------------------------------------------------------------------
string 本身的 erase 还是不错的,但是只能 erase 连续字符,如果要拿掉一个字符串里面所有的某个字符呢?用 STL 的 erase + remove_if 就可以了,注意光 remove_if 是不行的。
#include &iostream&
#include &algorithm&
#include &functional&
int main()
string str = &
hello, world. say bye
str.erase(remove_if(str.begin(),str.end(),
bind2nd(equal_to&char&(), ' ')),
str.end());
cout&&str.c_str()&&
上面的这段会拿掉所有的空格,于是得到 hello,world.saybye。
-----------------------------------------------------------------------
string 本身提供了 replace ,不过并不是面向字符串的,譬如我们最常用的把一个 substr 换成另一个 substr 的操作,就要做一点小组合:
#include &iostream&
int main()
string str(&hello, world&);
string sub(&ello, &);
str.replace(str.find(sub), sub.size(), &appy &);
cout&&str.c_str()&&
输出为 happy world。注意原来的那个 substr 和替换的 substr 并不一定要一样长。
-----------------------------------------------------------------------
startwith, endwith
这两个可真常用,不过如果你仔细看看 string 的接口,就会发现其实没必要专门提供这两个方法,已经有的接口可以干得很好:
#include &iostream&
int main()
string s(&hello, world&);
string head(&hello&);
string tail(&ld&);
bool startwith = s.compare(0, head.size(), head) == 0;
cout && boolalpha && startwith &&
bool endwith = s.compare(s.size() - tail.size(), tail.size(), tail) == 0;
cout && boolalpha && endwith &&
}当然了,没有 s.startwith(&hello&) 这样方便。
------------------------------------------------------------------------
toint, todouble, tobool...
这也是老生常谈了,无论是 C 的方法还是 C++ 的方法都可以,各有特色:
#include &iostream&
int main()
string s(&123&);
int i = atoi(s.c_str());
cout && i &&
string sd(&12.3&);
double d = atof(sd.c_str());
cout && d &&
string sb(&false&);
cout && boolalpha && sb.c_str() &&
的方法很简洁,而且赋值与转换在一句里面完成,而 C++ 的方法很通用。
------------------------------------------------------------------------
这可是件麻烦事,我们最希望的是这样一个接口: s.split(vect, '','') 。用 STL 算法来做有一定难度,我们可以从简单的开始,如果分隔符是空格、tab 和回车之类,那么这样就够了:
&&& string s(&hello world, bye.&);
&&& vector&string&
&&& vect.assign(
&&&&&&& istream_iterator&string&(stringstream(s)),
//此处编译出错,为什么?
&&&&&&& istream_iterator&string&()
不过要注意,如果 s 很大,那么会有效率上的隐忧,因为 stringstream 会 copy 一份 string 给自己用。
------------------------------------------------------------------------
把一个装有 string 的容器里面所有的 string 连接起来,怎么做?希望你不要说是 hand code 循环,这样做不是更好?
&&& vector&string&
&&& vect.push_back(&hello&);
&&& vect.push_back(&, &);
&&& vect.push_back(&world&);
&&& cout && accumulate(vect.begin(), vect.end(), string(&&));
//编译出错,为什么?
不过在效率上比较有优化余地。
-------------------------------------------------------------------------
其实我比较怀疑有什么人需要真的去 reverse 一个 string ,不过做这件事情的确是很容易:
std::reverse(s.begin(), s.end());
上面是原地反转的方法,如果需要反转到别的 string 里面,一样简单:
s1.assign(s.rbegin(), s.rend());
效率也相当理想。
-------------------------------------------------------------------------
解析文件扩展名
字数多点的写法:
&&& std::string filename(&hello.exe&);
&&& std::string::size_type pos = filename.rfind(''.'');
&&& std::string ext = filename.substr(pos == std::string::npos ? filename.length() : pos + 1);
不过两行,合并成一行呢?也不是不可以:
&&& std::string ext = filename.substr(filename.rfind(''.'') == std::string::npos ? filename.length() : filename.rfind(''.'') + 1);
我知道,rfind 执行了两次。不过第一,你可以希望编译器把它优化掉,其次,扩展名一般都很短,即便多执行一次,区别应该是相当微小。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:496704次
积分:5448
积分:5448
排名:第3814名
原创:66篇
转载:180篇
评论:39条
(5)(2)(5)(6)(4)(11)(3)(21)(3)(1)(3)(11)(4)(1)(5)(5)(1)(2)(1)(3)(3)(1)(10)(1)(3)(2)(2)(1)(2)(2)(3)(11)(6)(1)(3)(1)(8)(19)(10)(8)(3)(3)(6)(4)(4)(5)(1)(1)(3)(8)(1)(1)(3)(10)

我要回帖

更多关于 c string split方法 的文章

 

随机推荐