C++之split字符串分割

C++之split字符串分割在C++中没有直接对应的split函数,字符串分割可借助以下方法实现:1、借助strtok函数函数原型:char*strtok(char*str,char*delim);函数功能:以delim为分隔符分割字符串str参数说明:str:要分隔的字符串;delim:分隔符返回值:从str开头开始的一个个被分割的字符串。当没有被分割时则返回null代码1:直接使用s

大家好,又见面了,我是你们的朋友全栈君。

在C++中没有直接对应的split函数,字符串分割可借助以下方法实现:

1、借助strtok函数

函数原型:char * strtok (char *str, char * delim);

函数功能:以delim为分隔符分割字符串str

参数说明:str:要分隔的字符串;delim:分隔符

返回值:从str开头开始的一个个被分割的字符串。当没有被分割时则返回null

代码1:直接使用strtok函数分割char*类型的字符串

#include <iostream>
using namespace std;

int main() {
	char s[] = "my name is lmm";
	char *p;
	const char *delim = " ";
	p = strtok(s, delim);
	while(p) {
		cout << p << endl;
		p = strtok(NULL, delim);
	}

	return 0;
}


代码2:借助strtok分割string类型的字符串,将结果保存在vector<string>中

思路:先将整个string字符串转换为char*类型,分割后得到char*类型的子字符串,将子字符串转换为string类型,并存入结果数组中。

#include <iostream>
#include <vector>
using namespace std;

vector<string> split(const string& str, const string& delim) {
	vector<string> res;
	if("" == str) return res;
	//先将要切割的字符串从string类型转换为char*类型
	char * strs = new char[str.length() + 1] ; //不要忘了
	strcpy(strs, str.c_str()); 

	char * d = new char[delim.length() + 1];
	strcpy(d, delim.c_str());

	char *p = strtok(strs, d);
	while(p) {
		string s = p; //分割得到的字符串转换为string类型
		res.push_back(s); //存入结果数组
		p = strtok(NULL, d);
	}

	return res;
}

void test1() { //空字符串
	cout << "******test1****** "<<endl;
	string s = "";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}

void test2() { //只有一个字符串
	cout << "******test2****** " <<endl;
	string s = "my";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}

void test3() { //正常字符串
	cout << "******test3****** "<<endl;
	string s = "my name is lmm   ";//连续多个空格,空格会被过滤掉
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}


int main() {

	test1();
	test2();
	test3();
	return 0;
}


C++之split字符串分割

注意:test3中连续多个空格出现,空格都会被过滤掉

2、借助于string类的find和substr函数

1)find函数

函数原型:size_t find(const string& str, size_t pos = 0) const;

功能说明:从pos位置开始查找子字符串str第一次出现的位置

参数说明:str为要查找的子字符串,pos从为初始查找位置

返回值:找到的话返回子字符串第一次出现的位置,否则返回string::npos

2)substr函数

函数原型:string substr(size_t pos = 0, size_t n = npos) const;

功能说明:获取从指定的起始位置开始,长度为n的子字符串

参数说明:pos为起始位置,n获取的1字符串长度

返回值:子字符串

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
using namespace std;

string reverse_one_word(string str) {
	for(int i = 0; i < str.length()/2; i ++) {
		char tmp;
		tmp = str[i];
		str[i] = str[ str.length() - i - 1 ];
		str[ str.length() - i - 1 ] = tmp;
	}
	return str;
}

vector<string>  split(const string& str,const string& delim) { //将分割后的子字符串存储在vector中
	vector<string> res;
	if("" == str) return  res;
	
	string strs = str + delim; //*****扩展字符串以方便检索最后一个分隔出的字符串
	size_t pos;
	size_t size = strs.size();

	for (int i = 0; i < size; ++i) {
		pos = strs.find(delim, i); //pos为分隔符第一次出现的位置,从i到pos之前的字符串是分隔出来的字符串
		if( pos < size) { //如果查找到,如果没有查找到分隔符,pos为string::npos
			string s = strs.substr(i, pos - i);//*****从i开始长度为pos-i的子字符串
			res.push_back(s);//两个连续空格之间切割出的字符串为空字符串,这里没有判断s是否为空,所以最后的结果中有空字符的输出,
			i = pos + delim.size() - 1;
		}
		
	}
	return res;	
}

void test1() { //空字符串
	cout << "******test1****** "<<endl;
	string s = "";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}

void test2() { //只有一个字符串
	cout << "******test2****** " <<endl;
	string s = "my";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}

void test3() { //正常字符串
	cout << "******test3****** "<<endl;
	string s = "my name is  lmm   ";
	
	std::vector<string> res = split(s, " ");
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] <<endl;
	}
}


int main() {

	test1();
	test2();
	test3();
	return 0;
}

C++之split字符串分割

注意:test3中的多个空格未被过滤掉,也就是说两个空格分隔符之间的空子串也被存进了结果数组中。要想避免这个问题可以在分隔出子字符串s时,判断一下若为空(两个分隔符相邻,中间的子串为空),则不加入字符数组即可去掉。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132456.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • dual channel ddr3主板_ddr3 std

    dual channel ddr3主板_ddr3 std第一次看到ODT这个东西,真是一头雾水;然后是TerminationRank,FAE解释了几次,也没明白。究其原因,这玩意儿和硬件太相关,而不是纯粹软件的TRUEorFALSE。好歹也是通信工程毕业,号称软硬通吃,怎能被轻易难倒?ODT,全称OnDieTermination。我们先说Termination的概念。一个DDR通道,通常会挂接多个Rank,这些Rank的数

    2025年10月15日
    2
  • IOS 语法 – 关于 NStimer 中 scheduledTimerWithTimeInterval方法传参的问题「建议收藏」

    IOS 语法 – 关于 NStimer 中 scheduledTimerWithTimeInterval方法传参的问题「建议收藏」使用NSTimerscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:的时候有两个地方需要注意。首先select

    2022年7月1日
    67
  • 常见希腊字母的发音对照表

    常见希腊字母的发音对照表点我查看

    2025年11月3日
    2
  • 计算机快捷键任务管理器,任务管理器快捷键,小编教你电脑如何打开任务管理器…

    计算机快捷键任务管理器,任务管理器快捷键,小编教你电脑如何打开任务管理器…很多时候,我们需要用到任务管理器,通过系统中自带的任务管理器,我们可以查看到当前运行的应用程序、进程、硬件使用情况等。对于电脑小白来说,不知道任务管理器怎么打开,因此,小编给大家整理这篇打开任务管理器的图文。电脑系统的任务管理器是Windows提供有关计算机性能的信息,并显示了计算机上所运行的程序和进程的详细信息,从这里可以查看到当前系统的进程数、CPU使用比率、更改的内存、容量等数据。那么,任务…

    2022年6月18日
    19
  • 彻底明白vue双向绑定底层原理(源码分析)

    彻底明白vue双向绑定底层原理(源码分析)vue是一个mvvm框架,双向绑定是vue的一个核心功能,所谓双向绑定就是当试图发生改变的时候传递给VM(ViewModel),让数据得到更新,当数据发生改变的时候传给VM(ViewModel),使得视图发生变化!概念都知道,但是vue怎么做到的呢?看下面的一张图(图是搬运别人的)可能你现在看不明白,observer是什么东西,watchter,Dep又是什么东西?没有关系,接下来只要你看完我这篇文章,保证给你整的明明白白!看上图,从左边开始newMVVM其实就是我newVue(),我们一

    2022年9月14日
    2
  • rsync自动同步_文件实时同步

    rsync自动同步_文件实时同步文章目录一、rsync同步简介1.关于rsync2.rsync同步源(备份源)二、配置rsync备份源1.关闭防火墙2.查看rsync是否已安装,一般系统已默认安装rsync3.建立/etc/rsync.conf配置文件4.为备份账户创建数据文件5.保证所有用户对源目录/var/www/html都有读取权限6.启动rsync服务程序7.关闭rsync服务8.编写测试网页三、rsync命令基本用法1.基本格式2.常用选项四、配置发起端1.关闭防火墙2.查看rsync是否已安装,一般

    2022年10月13日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号