C++ strtok()无法截取连续两个分隔符之间的空字符串, 解决方法

2023-05-16

前言

  • 问题描述:
    与前台约定按顺序解析对应信息, 如果中间出现空数据(或者出现连续两个分隔符), strtok就会出问题.

看下面这个例子:

  1 #include <string.h>
  2 #include <stdio.h>
  3 
  4 int main()
  5 {
  6     char str[] = "abc||de|fghi";
  7 
  8     char* p = strtok(str, "|");
  9     for(int i = 0; p != NULL; ++i)
 10     {
 11         printf("substr[%d]:%s\n", i, p);
 12         p = strtok(NULL, "|");
 13     }
 14 
 15     return 0;
 16 }


源字符串为:“abc||de|fghi”
分隔符为: ‘|’
运行结果为:
这里写图片描述

中间abc与de之间的连续两个’|’, strtok在分隔的时候, 直接把空字符串跳过了,
而有的时候, 即使分隔符间是空字符串, 我们也是需要获取的;
那么此时strtok就无法满足需要了, 下面是我用c++实现的, 可以截取空串的方法.

方法介绍

#include <stdio.h>
#include <string>
#include <vector>
/*
名称:my_split(const std::string& src, const char& delim,
         std::vector<std::string>& vec)

功能:用分隔符将源字符串分隔为多个子串并传出; n个分隔符, 分n+1个子串
    

参数:
     src-传入参数, 源字符串;
     delim-传入参数, 分隔符;
     vec-传出参数, 子串的集合;
  
返回值:
    0-成功;
    其它-失败;
 */

int my_split(const std::string& src, const char& delim,
		std::vector<std::string>& vec)
{
	int src_len = src.length();
	int find_cursor = 0;
	int read_cursor = 0;

	if (src_len <= 0) return -1;

	vec.clear();
	while (read_cursor < src_len){

		find_cursor = src.find(delim, find_cursor);

		//1.找不到分隔符
		if (-1 == find_cursor){
			if (read_cursor <= 0) return -1;

			//最后一个子串, src结尾没有分隔符
			if (read_cursor < src_len){
				vec.push_back(src.substr(read_cursor, src_len - read_cursor));
				return 0;
			}
		}
		//2.有连续分隔符的情况
		else if (find_cursor == read_cursor){
			//字符串开头为分隔符, 也按空子串处理, 如不需要可加上判断&&(read_cursor!=0)
			vec.push_back(std::string(""));
		}
		//3.找到分隔符
		else
			vec.push_back(src.substr(read_cursor, find_cursor - read_cursor));

		read_cursor = ++find_cursor;
		if (read_cursor == src_len){
			//字符串以分隔符结尾, 如不需要末尾空子串, 直接return
			vec.push_back(std::string(""));
			return 0;
		} 
	}//end while()

	return 0;
}

调用

int main(int argc, char* argv[])
{
	std::vector<std::string> vecSrc;
	std::vector<std::string> vecSplit;

	vecSrc.push_back(std::string("|Hello||world|"));
	vecSrc.push_back(std::string("Hello||world"));

	for (auto src : vecSrc){
	   vecSplit.clear();
		int iRet = my_split(src, '|', vecSplit);
		if (0 == iRet){
			printf("src:%s, vecSplit.size():%d\n", src.c_str(), vecSplit.size());

			int idex = 0;
			for (auto it : vecSplit)
				printf("vec[%d]:%s\n", idex++, it.c_str());
		}
		printf("---------------------------------\n");
	}

	return 0;
}

运行结果:
这里写图片描述

可以看到, Hello和World之间的空字符串, 也能通过分隔符截取出来了.
如果开头或结尾有分隔符, 会将开头或结尾处都截出空子串,
类似刀切割绳子, 即:n个分隔符, 必有n+1个子串;
若不需要开头和结尾分隔子串, 可参照注释修改两行代码即可.

结语

上述方法比strtok有以下优点:

  • 没有用到static变量, 故线程安全;
  • 传入源字符串为const引用, 不会改变源字符串;
  • 可以截取到连续分隔符间的空串;
  • 如果首次未找到分隔符将会返回失败, 而strtok会返回源字符串

如有不足, 望不吝赐教, 感谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ strtok()无法截取连续两个分隔符之间的空字符串, 解决方法 的相关文章

  • MySQL数据库安装步骤及报错1251解决方法

    MySQL数据库安装 MySQL是一种关系数据库管理系统 xff0c 所使用的 SQL 语言是用于访问数据库的最常用的标准化语言 xff0c 其特点为体积小 速度快 总体拥有成本低 xff0c 尤其是开放源码这一特点 xff0c 在 Web
  • 【Oracle】ORA-28000解决方法

    ORA 28000 账号被锁定 错误原因 xff1a 数据库中设置了密码最 错误次数为10次 xff0c 超过10次后导致账号被锁定 解决方案1 xff1a 1 查看 户使 的概要 件名 xff0c 般为DEFAULT SELECT USE
  • C语言strtok函数

    1 strtok 语法 include lt string h gt char strtok char str const char delimiters 参数 xff1a str xff0c 待分割的字符串 xff08 c string
  • 关于strtok的使用

    1功能 xff1a strtok是一个比较特殊的 xff0c 用于切割字符串的函数 2 使用我们先来看一下strtok的使用 strtok C 43 43 Reference char strtok xff08 char str xff0c
  • matlab学习(1)strsplit与strtok

    strsplit函数用法 xff1a lt 1 gt 默认使用空格符分割 返回一个cell数组 lt 2 gt 也可以指定第二个参数进行分割 lt 3 gt 第二个参数也可以时包含多个分隔符的元胞数组 lt 4 gt strsplit还可以
  • SSH无法登陆服务器,但是可以ping通,解决方法

    SSH无法登陆服务器 xff0c 但是可以ping通 xff0c 解决方法 参考文章 xff1a xff08 1 xff09 SSH无法登陆服务器 xff0c 但是可以ping通 xff0c 解决方法 xff08 2 xff09 https
  • emWin 卡顿 触屏失效 黑屏 解决方法

    emWin初体验 刚学了uC OS体验到了操作系统的方便 xff0c 于是想体验下图形处理第三方的强大 xff0c emWin便是首选 我移植emWin一共遇到了两个问题 1 一直黑屏 最后实在整不出来 xff0c 有点郁闷 把例程和自己的
  • ubuntu 16.04无法locate boot-repair的解决方法

    ubuntu16 04 07加windows10后无法启动ubunu的问题解决boot repair的安装方法同样适用于ubuntu18 04 ubuntu20 01等系统不能启动的问题 对boot repair修复的原理进行分析 文章目录
  • 无法安装net framework 3.5 的解决方法

    电脑刚重装了Windows8 1系统 xff0c 然后安装数据库的时候 xff0c 却出现了这样的问题 xff1a 您的电脑上的应用需要使用以下windows功能 问题原因是 xff1a 在安装系统的时候 xff0c NET Framewo
  • VINS-Fusion运行时的段错误(核心已转储)解决方法

    平台 ubuntu16 04 43 ROS 问题描述 xff1a 前两天VINS的原作者开源了VINS Fusion的双目版以及给出了和GPS融合的一个demo xff0c 所以试着运行下数据集 每次单目运行10s左右 xff0c 双目1
  • 从 strtok() 获取零长度字符串

    我有一个 CSV 文件 其中包含以下数据 value name test etc 我试图通过使用来分割strtok string 但是 该文件可以包含零长度数据 如下所示 value test etc which strtok 跳过 有什么
  • 意外的 strtok() 行为

    我正在尝试使用 strtok 计算文件中的单词数 code c WHAT Use strtok to count the number of words in a file include
  • C++ strtok - 多次使用更多数据缓冲区

    我使用时没有什么问题strtok 功能 我正在解析两个文件 首先我将文件 1 加载到buffer 该文件包含我需要加载的第二个文件的名称 这两个文件都是逐行读取的 我的代码如下所示 char second file name 128 cha
  • C:strtok_r的正确用法

    如何使用 strtok r 而不是 strtok 来执行此操作 char pchE strtok NULL 现在我正在尝试使用strtok r正确 但有时我会遇到问题strtol 我有一个线程 同时 执行 10 次 char savedEn
  • 罢工行为

    int main char str kk 12 23 4 3434 3 33 char valarr int count 0 valarr strtok str while valarr 0 valarr strtok NULL count
  • strtok 未处理的异常;写入位置访问冲突

    include
  • C 的 strtok() 和只读字符串文字

    char strtok c har s1 const char s2 重复调用此函数将字符串 s1 分解为 标记 即 字符串被分成子字符串 每个都以 0 结尾 其中 0 替换任何字符 包含在字符串 s2 中 第一次通话 使用要标记为 s1
  • 开发了 strtok 替代品

    我开发了自己的 strtok 版本 只是为了练习指针的使用 任何人都可以看到这有任何限制 或者无论如何我可以改进 void stvstrtok const char source char dest const char token Sea
  • 如何在 Teradata 14 中对子字符串进行分组?

    我有下表天睿14 我不允许自己编写过程和函数 但我可以使用strtok strtok split to table etc id property 1 1234X Yel 2225Y Red 1234X Gre 2 3 1222Y Pin
  • 需要使用 strtok() 知道两个标记分隔符之间何时没有数据出现

    我正在尝试标记一个字符串 但我需要确切地知道两个标记之间何时看不到数据 例如 当标记以下字符串时 a b c d e 我需要知道 之间的两个空槽d and e 我无法简单地使用strtok 我的尝试如下所示 char arr fields

随机推荐