如:

string str1 = "This is a test";
string str2 = "This-is-a-test";
string str2 = "This+is+a+test";

我们如何将以上字符串按照某种分隔符( ,-,+),将其分割成四个子串,其值分别为 “This” “is” “a” “test” 。

一、使用stringstream流

这里我们只需要用到 istringstream(字符串输入流) 构造字符串流,然后从字符串流中按照一定的格式读取数据即可。

通常我们使用 cin 从流中读取数据,而我们也可以使用 getline 读取,而后者在读取时可以选择接受的数据格式,其函数原型如下:

// istream & getline(char* buf, int bufSize);    // 读到 \n 为止
istream & getline(char* buf, int bufSize, char delim); //读到 delim 字符为止// \n 或 delim 都不会被读入 buf,但会被从文件输入流缓冲区中取走

因此,我们可以按照此方式设计一个C++中的string split函数。

void Stringsplit(string str,const const char split)
{istringstream iss(str);    // 输入流string token;         // 接收缓冲区while (getline(iss, token, split))  // 以split为分隔符{cout << token << endl; // 输出}
}

如此,我们就设计出了我们的Stringsplit() 函数。该函数有以下 2 种语法格式

void Stringsplit(string str,const const char split);
// 默认将传入的字符串str以split为分隔符进行分割,并将得到的子串打印在屏幕上,无返回值
void Stringsplit(string str, const const char split,vector<string>& rst);
// 默认将传入的字符串str以split为分隔符进行分割,    不会将子串打印在屏幕上,无返回值
//                  分割的子串将会保存在rst数组中被带出函数。

以上,我们简单的设计了一种C++中的分割字符串的函数,下面来看一个测试用例:

int main() {string str("This is a test");Stringsplit(str, ' ');      // 打印子串vector<string> strList;string str2("This-is-a-test");Stringsplit(str2, '-', strList);  // 将子串存放到strList中for (auto s : strList)cout << s << " ";cout << endl;return 0;
}
# 输出
This
is
a
test
This is a test

二、使用string类提供的find方法与substr方法

find函数原型: 

size_type find( const basic_string& str, size_type pos = 0 ) const;

参数:
str - 要搜索的 string , pos - 开始搜索的位置
返回值
找到的子串的首字符位置,或若找不到这种子串则为 npos 。

substr函数原型:

basic_string substr( size_type pos = 0, size_type count = npos ) const;

参数:
pos - 要包含的首个字符的位置 ,count - 子串的长度
返回值
含子串 [pos, pos+count) 的 string 。

由以上两个函数我们便可以设计出我们的Stringsplit()来。同时,因为find()函数查找的可以是字符串,因此我们的分隔符可以是单个的字符,也可以是一个字符串。

// 使用字符分割
void Stringsplit(const string& str, const char split, vector<string>& res)
{if (str == "")     return;//在字符串末尾也加入分隔符,方便截取最后一段string strs = str + split;size_t pos = strs.find(split);// 若找不到内容则字符串搜索函数返回 nposwhile (pos != strs.npos){string temp = strs.substr(0, pos);res.push_back(temp);//去掉已分割的字符串,在剩下的字符串中进行分割strs = strs.substr(pos + 1, strs.size());pos = strs.find(split);}
}
// 使用字符串分割
void Stringsplit(const string& str, const string& splits, vector<string>& res)
{if (str == "")     return;//在字符串末尾也加入分隔符,方便截取最后一段string strs = str + splits;size_t pos = strs.find(splits);int step = splits.size();// 若找不到内容则字符串搜索函数返回 nposwhile (pos != strs.npos){string temp = strs.substr(0, pos);res.push_back(temp);//去掉已分割的字符串,在剩下的字符串中进行分割strs = strs.substr(pos + step, strs.size());pos = strs.find(splits);}
}

下面是一个测试用例:

int main()
{vector<string> strList;string str("This-is-a-test");Stringsplit(str, '-', strList);for (auto s : strList)cout << s << " ";cout << endl;vector<string> strList2;string str2("This%20is%20a%20test");Stringsplit(str2, "%20", strList2);for (auto s : strList2)cout << s << " ";cout << endl;return 0;
}
# 输出
This is a test
This is a test

三、使用C库函数strtok

char* strtok( char* str, const char* delim );

参数:
str - 指向要记号化的空终止字节字符串的指针
delim - 指向标识分隔符的空终止字节字符串的指针
返回值:
指向下个记号起始的指针,或若无更多记号则为空指针。

需要注意的是,该函数使用一个全局的静态变量来保存每次分割后的位置,因此在多线程中是不安全的,这里我们也可以选择使用它的线程安全版本

 char *strtok_r(char *str, const char *delim, char **saveptr); 。
void Stringsplit(const string& str, const string& split, vector<string>& res)
{char* strc = new char[str.size() + 1];strcpy(strc, str.c_str());   // 将str拷贝到 char类型的strc中char* temp = strtok(strc, split.c_str());while (temp != NULL){res.push_back(string(temp));       temp = strtok(NULL, split.c_str());    // 下一个被分割的串}delete[] strc;
}

如此,我们的使用 strtok 版本的Stringsplit() 就完成了。不过,我们使用这种方法实现的字符串分割函数只能根据字符来分割,而我们传入的参数是字符串类型,这样可能会对函数的使用这造成误导(注:参数传入字符串用的双引号,传入字符用的单引号),因此我们也可以使用下面的方法封装一个参数是字符类型的函数。

void Stringsplit(const string& str, const char split, vector<string>& res)
{Stringsplit(str, string(1,split), res);    // 调用上一个版本的Stringsplit()
}

下面给出一个测试用例,我们分别使用单/双引号传入分割的限定字符。

int main()
{vector<string> strList;string str("This+is+a+test");Stringsplit(str, '+', strList);for (auto s : strList)cout << s << " ";cout << endl;vector<string> strList2;string str2("This-is-a-test");Stringsplit(str2, "-", strList2);for (auto s : strList2)cout << s << " ";cout << endl;return 0;
}

四、使用regex_token_iterator(正则表达式)

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

而在C++的正则中,把这种操作称为Tokenize分词(或者叫切割)。这种操作刚好可以满足我们的需求,用模板类regex_token_iterator<>提供分词迭代器,可以完成字符串的分割。

void Stringsplit(const string& str, const string& split, vector<string>& res)
{//std::regex ws_re("\\s+"); // 正则表达式,匹配空格 std::regex reg(split);        // 匹配splitstd::sregex_token_iterator pos(str.begin(), str.end(), reg, -1);decltype(pos) end;              // 自动推导类型 for (; pos != end; ++pos){res.push_back(pos->str());}
}

测试用例:

int main()
{// 单个字符分词vector<string> strList;string str("This is a test");Stringsplit(str," ", strList);for (auto s : strList)cout << s << " ";cout << endl;// 使用字符串分词vector<string> strList2;string str2("ThisABCisABCaABCtest");Stringsplit(str2, "ABC", strList2);for (auto s : strList2)cout << s << " ";cout << endl;
}
# 输出
This is a test
This is a test

C++中string如何实现字符串分割函数split()——4种方法相关推荐

  1. c语言将字符串按空格分割_如何在c++中实现字符串分割函数split详解

    前言 在学习c++中string相关基本用法的时候,发现了sstream的istringstream[1]可以将字符串类似于控制台的方式进行输入,而实质上这个行为等同于利用空格将一个字符串进行了分割, ...

  2. c语言中字符切割函数split,c 语言 指针 C语言字符串分割函数split实现

    c语言也有类似其他语言的split字符串分割函数,就是strtok使用方法如下://用逗号做分隔符,读出内容//char s[] = "123-sldkf-123ls-343434-dfjd ...

  3. C++实现字符串分割函数split()

    目录 使用strtok()完成分割 使用strsep()完成分割 使用strtok_r()完成分割 实现字符串分割 前言 最近遇到了一个字符串分割的问题,在C++的标准库里面没有字符分割函数split ...

  4. Java字符串分割函数split

    Java中的我们可以利用split把字符串按照指定的分割符进行分割,然后返回字符串数组,下面是string.split的用法实例及注意事项: 1.split 方法  将一个字符串分割为子字符串,然后将 ...

  5. 如何字符串拷贝函数的几种方法,你猜哪个效率最高?

    strcpy,即string copy(字符串复制)的缩写. 是C语言标准库中实现字符串拷贝的一个函数. 各大公司笔试题最喜欢考的一道题,快来看看,你会几种方法? 问:你会如何实现这个函数呢? 1 v ...

  6. java对于 进行字符串分隔_Java字符串分割函数split中以·点分割的问题

    问题描述: // 把字符串"192.168.1.1"按照小圆点进行分割,分割成"192","168","1"," ...

  7. SQL Server自定义字符串分割函数——Split

    我相信大部分人都碰到过,处理数据的时候,字段的值是以 ',' (逗号)分隔的形式,所以我也不能避免. 然后我才知道,sql 是没有类似于 C# 和 Javascript 这种分割字符串的方法.( Sp ...

  8. C++的字符串分割函数

    转载:http://blog.csdn.net/shanzhizi/article/details/17189267 C++的字符串没有分割函数,因此需要自己写方便使用.而受到开发工具的影响,有很多用 ...

  9. php中的分割字符串函数,关于PHP中两款字符串分割函数explode,str_split

    关于PHP中两款字符串分割函数explode,str_split 2019.02.19 4140 将一个字符串分割成数组在日常的微信公众号开发中的应用应该是很多的.如果指定分割符,可以使用explod ...

最新文章

  1. Python开发编码规范(转)
  2. 视图解析jstlView支持便捷的国际化功能
  3. Mule3用户手册:Mule ESB 3使用要点
  4. python读取nc文件并转换成csv_Python提取netCDF数据并转换为csv文件
  5. window2003 server的一些优化设置_windows 2003
  6. Asp.Net Core WebAPI使用Swagger时API隐藏与分组
  7. NTT通信公司在大阪开通运营容灾数据中心
  8. atitit.细节决定成败的适合情形与缺点
  9. eclips3.4.2 添加 tomcat6.0不可用解决——重新搞
  10. [转载] python自带sqlite库_Python内置库SQlite3使用指南
  11. vue中将汉字按照首字母排序,也适用于其他地方,但不适用多音字
  12. 上传文件中文乱码问题修复
  13. python 使用前馈神经网络处理IrIs数据集(BP)
  14. 无线手柄在ROS上的使用
  15. 300 秒就完成第一超算 1 万年的计算量,量子霸权真时代要来了吗
  16. 信息系统项目管理师考前10天极限冲刺+答案(七)
  17. Xshell连接虚拟机linux
  18. 线程池2nd卷:虎落平阳被犬欺
  19. 【雅思大作文考官范文】——第三篇:essay 'skeleton'(散文“骨架”)
  20. 项目1在线交流平台-4. 使用radis高性能储存方案-1.redis入门-特点、安装与支持数据类型

热门文章

  1. Linux服务器Service Unavailable 原因与解决办法
  2. Codeforces Round #629(Div.3)
  3. 软件测试笔试题(四)
  4. c语言编译器mingw——常用编译命令
  5. 毛哥的快乐生活(25) Servlet版新闻网站之需求分析
  6. Mikrotik路由系统升级方式
  7. python+matlab:统计双色球出号分布
  8. Contest - 第10届“新秀杯”ACM程序设计大赛网络资格赛 赛后信息(题解)
  9. 毕达哥拉斯树(pythagorasTree)原理解析及canvas动画实现
  10. css,一些经常忘掉的简单布局 笔记