当前位置: 首页 > news >正文

strtok()的用法及实现哦

1. 用法

1. 声明:char *strtok(char *str, const char *delim)

  • str -- 要被分解成一组小字符串的字符串。第一次调用 strtok() 时,这个参数应该是你想要分割的字符串。随后的调用应该将此参数设置为NULL,以便继续从上次的位置分割。
  • delim -- 包含分隔符的 C 字符串。

2. 作用:strtok() 用于将字符串分割成一系列的子串

3. 返回值:该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

     贝蒂说:“如果一下子没有明白,不要但心,继续跟着贝蒂看看例子就明白啦~”  

 2. 实例

#include <string.h>
#include <stdio.h>
int main() 
{char str[80] = "This is - betty -@class";const char s[] = "-@";char* p = strtok(str, s);//第一次传参while (*p != NULL){printf("%s\n", p);p = strtok(NULL, s);//非第一次传参}return 0;
}

输出结果:

This is
 betty
 class 

    简单来说:“strtok()就是把从目标字符串中,以分隔符为标志,将其分成若干个子串,并且需要多次调用” 

3. 实现 

思路分析:

第一步:

先判断是否为第一次传入 

第二步:

分割起始的分割符,我们先假设需要在“@+abc”中切割“@+”

  1. 首先判定p1中首元素是否需要切割(在p2中排查直到遇见‘\0’)。

  2. 如果匹配成功,让pp+1指向下一个元素,让p3重新指向p2的首元素,继续排查下一个元素。

  3. 如果排查失败,p2或pp指向‘\0’,如果p2指向'\0',说明起始位置的分割符排查成功,如果pp指向‘\0’,说明没有再分割的字符串,返回NULL。

assert(p2);//防止p2为空指针
static char* pp= NULL;//static修饰,延长其生命周期
//让其第二次调用时后能指向下一个字符串
char* ret = NULL;//作为返回值
char* p3 = (char*)p2;//记录p2的初始位置
if (p1 != NULL)
{pp = p1;//第一次传入
}
while (*pp && *p2)//排除起始的分割符
{if (*p2 == *pp){pp++;p2 = p3;//成功找到再重新匹配}else{p2++;//匹配下一个字符}
}

 第三步:

 分割后续字符串,我们假设在“ab@cd”中分割“@”。

ret = pp;//记录初始位置,方便返回
p2 = p3;//让p2指向初始位置
while (*pp && (*pp!= *p2++))//开始匹配
{if (*p2=='\0'){pp++;//判断下一个字符p2 = p3;//让p2重新开始匹配}
}
if (*pp)//判断是不是'\0'
{*pp++ = '\0';//分割字符串,并指向下一个字符
}
return ret;

 第四步:

当非第一步传入时,*pp==‘\0’时,说明分割结束,返回NULL.

if (p1 == NULL && pp=='\0')//查找完毕
{return NULL;//最后返回空指针
}

完整代码:
 

#include <assert.h>
#include <stdio.h>
char* my_strtok(char* p1, const char* p2)
{assert(p2);//防止p2为空指针static char* pp= NULL;//static修饰,延长其生命周期//让其第二次调用时后能指向下一个字符串char* ret = NULL;//作为返回值char* p3 = (char*)p2;//记录p2的初始位置if (p1 == NULL && pp=='\0')//查找完毕{return NULL;//最后返回空指针}if (p1 != NULL){pp = p1;//第一次传入}while (*pp && *p2)//排除起始的分割符{if (*p2 == *pp){pp++;p2 = p3;//成功找到再重新匹配}else{p2++;//匹配下一个字符}}if (*pp = '\0'){return NULL;//第一次排查指向'\0'}ret = pp;//记录初始位置,方便返回p2 = p3;//让p2指向初始位置while (*pp && (*pp!= *p2++))//开始匹配{if (*p2=='\0'){pp++;//判断下一个字符p2 = p3;//让p2重新开始匹配}}if (*pp)//判断是不是'\0'{*pp++ = '\0';//分割字符串,并指向下一个字符}return ret;
}

贝蒂说:“这应该算是字符串函数最难实现的吧,贝蒂思考了好久的说~”

相关文章:

  • 逻辑回归的介绍和应用
  • es模板和索引简单操作简介
  • rust宏(macro)详解
  • Selenium+Unittest+HTMLTestRunner框架更改为Selenium+Pytest+Allure(一)
  • Sui承诺向流动性质押协议投入$SUI
  • TimescaleDB-1 安装
  • 3D渲染和动画制作软件KeyShot Pro mac附加功能
  • CRM客户管理系统-超详细介绍
  • 机器人视觉
  • OTP语音芯片与可重复擦写(Flash型)语音芯片:特性比较与应用差异
  • CanEasy多场景应用,让汽车总线测试更简单
  • 差分法详解
  • Java集合中的通用算法,开发效率翻倍
  • 【源码】车牌检测+QT界面+附带数据库
  • UE虚幻引擎中程序无需运行也可调试
  • AHK 中 = 和 == 等比较运算符的用法
  • PHP那些事儿
  • scrapy学习之路4(itemloder的使用)
  • vue2.0项目引入element-ui
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 前端技术周刊 2019-02-11 Serverless
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​MySQL主从复制一致性检测
  • ​用户画像从0到100的构建思路
  • #Lua:Lua调用C++生成的DLL库
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • #预处理和函数的对比以及条件编译
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2.2w字)前端单元测试之Jest详解篇
  • (20050108)又读《平凡的世界》
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 回调、接口回调、 委托
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NetCore部署微服务(二)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • @Service注解让spring找到你的Service bean
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [100天算法】-目标和(day 79)
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [E单调栈] lc2487. 从链表中移除节点(单调栈+递归+反转链表+多思路)