超详细讲解字符串查找函数(保姆级教程!!!)
超详细讲解字符串查找函数(保姆级教程!!!)
- 字符串查找函数
- strstr函数
- strstr函数的使用
- strstr函数的模拟实现
- strtok函数
- strtok函数的使用
- strtok函数的模拟实现
- strpbrk函数
- strpbrk函数的使用
- strpbrk函数的模拟实现
- strcspn函数
- strcspn函数的使用
- strcspn函数的模拟实现
- strspn函数
- strspn函数的使用
- strspn函数的模拟实现
字符串查找函数
strstr函数
strstr函数是在字符串 str1 中查找第一次出现字符串 str2的位置,不包含终止符 ‘\0’。
str1 – 要被检索的 C 字符串。
str2 – 在 str1 字符串内要搜索的小字符串。
strstr函数的使用
下面是strstr函数的使用例子:
/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");strncpy (pch,"sample",6);puts (str);return 0;
}
strstr函数的模拟实现
要在str1中查找str2并打印出来,先判断str1和str2指向的字符是否相等,此时有两种情况:
第一种情况指向的字符不相等,str1要指向下一个字符,再判断,如此循环往复,当str1指向的是 ‘\0’ 时,可以判断出str1中不存在str2,此时返回NULL;
第二种情况下指向的字符相等,那么不仅str1要向后读取字符,str2也要向后读取字符,再判断是否相等。
strstr函数的模拟实现如下:
char * strstr (const char * str1, const char * str2) {char *cp = (char *) str1;char *s1, *s2;if ( !*str2 )return((char *)str1);while (*cp){s1 = cp;s2 = (char *) str2;while ( *s1 && *s2 && !(*s1-*s2) )s1++, s2++;if (!*s2)return(cp);cp++;}return(NULL);
而实现strstr函数,除了上述的偏暴力算法的模拟实现方式之外,还可以通过KMP算法进行实现。
KMP算法:Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP算法”,常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法。
算法的核心思想是:
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。
具体的KMP算法思想编者会另行写一篇文章向大家大致阐述,这里就不多在赘述,有兴趣的读者可以去了解一下。
strtok函数
char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
str – 要被分解成一组小字符串的字符串。
delim – 包含分隔符的 C 字符串。
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
strtok函数的使用
下面演示strtok函数的用法:
#include <string.h>
#include <stdio.h>int main () {char str[80] = "This is - www.xxxxx.com - website";const char s[2] = "-";char *tmp;tmp = strtok(str, s);while( tmp != NULL ) {printf( "%s\n", tmp );tmp = strtok(NULL, s);}return(0);
}
编译并运行上面的程序将产生以下结果:
This is
www.xxxxx.com
website
原字符串的改动是切分符原位置均更改为 ‘\0’,所以内容都还在
strtok函数具有以下的特点:
1、delim参数是个字符串,定义了用作分隔符的字符集合
2、第一个参数指定一个字符串,它包含了0个或者多个由delim字符串中一个或者多个分隔符分割的标记。
3、strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
4、strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。
5、strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
6、strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
7、如果字符串中不存在更多的标记,则返回 NULL 指针。
strtok函数的模拟实现
char* my_strtok(char* str, const char* sep)
{static char* s1 = NULL;static char* s2 = NULL;static int len1 = 0;static int count = 0;int len2 = 0;int i = 0;assert(sep != NULL);if (str != NULL) {s1 = str; len1 = strlen(str);len2 = strlen(sep);for (*str;*str != '\0';str++) {for (i = 0;i < len2;i++) {if (i == 0){count++;}if (*str == *(sep + i)) {*str = '\0'; s2 = str; return s1;}}}}else{s1 = s2 + 1; len2 = strlen(sep);str = s1; for (*str;*str != '\0';str++) {for (i = 0;i < len2;i++) {if (i == 0){count++;}if (*str == *(sep + i)) {*str = '\0'; s2 = str;return s1;}}}}if (count > len1){return NULL;}return s1;
}
strpbrk函数
char *strpbrk(const char *str1, const char *str2) 检索字符串 str1 中第一个匹配字符串 str2 中字符的字符,不包含空结束字符。也就是说,依次检验字符串 str1 中的字符,当被检验字符在字符串 str2 中也包含时,则停止检验,并返回该字符位置。
str1 – 要被检索的 C 字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。
strpbrk函数的使用
下面展示strpbrk函数的使用:
#include <stdio.h>
#include <string.h>int main ()
{const char str1[] = "abcde2fghi3jk4l";const char str2[] = "34";char *ret;ret = strpbrk(str1, str2);if(ret) {printf("第一个匹配的字符是: %c\n", *ret);}else {printf("未找到字符");}return(0);
}
强调的是,找的是str1中,str2的第一个匹配的内容的地址。
strpbrk函数的模拟实现
char* find_char(char const* str1, char const* str2)
{assert(str1 != NULL);assert(str2 != NULL);char* tmp = (char*)str2;while (*tmp != '\0'){char* pso = (char*)str1;while (*pso != '\0'){if (*pso != *tmp){++pso;}else{return pso;}}tmp++;}return 0;
}
strcspn函数
size_t strcspn(const char *str1, const char *str2) 检索字符串 str1 开头连续有几个字符都不含字符串 str2 中的字符。
str1 – 要被检索的字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。
strcspn函数的使用
下面演示strcspn函数的用法:
#include <stdio.h>
#include <string.h>int main ()
{int len;const char str1[] = "ABCDEF4960910";const char str2[] = "013";len = strcspn(str1, str2);printf("第一个匹配的字符是在 %d\n", len + 1);return(0);
}
编译并运行上面的程序将产生以下结果:
第一个匹配的字符是在 10
strcspn函数的模拟实现
size_t my_strcspn(const char* str1, const char* str2)
{int i = 0;char* pstr1 = (char*)str1;assert(NULL != str1);assert(NULL != str2);while (*pstr1){char* pstr2 = (char*)str2;while (*pstr2 && *pstr1 != *pstr2)++pstr2;if (*pstr1 == *pstr2)break;++pstr1;}return (pstr1 - str1);
}
strspn函数
size_t strspn(const char *str1, const char *str2) 检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标。
str1 – 要被检索的字符串。
str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。该函数返回 str1 中第一个不在字符串 str2 中出现的字符下标。
strspn函数的使用
下面演示 strspn函数的用法:
#include <stdio.h>
#include <string.h>int main ()
{int len;const char str1[] = "ABCDEFG019874";const char str2[] = "ABCD";len = strspn(str1, str2);printf("初始段匹配长度 %d\n", len );return(0);
}
编译并运行上面的程序将产生以下结果:
初始段匹配长度 4
strspn函数的模拟实现
size_t my_strspn(const char* str1, const char* str2)
{int i = 0;char* pstr1 = (char*)str1;assert(NULL != str1);assert(NULL != str2);while (*pstr1){char* pstr2 = (char*)str2;while (*pstr2 && *pstr1 != *pstr2)++pstr2;if (*pstr1 == *pstr2)break;++pstr1;}return (pstr1 - str1);
}
那么,今天的C语言 柔性数组的使用详解的相关内容我就讲述完啦,因为个人能力有限,文章难免会出现纰漏,届时有错误可以私信发给我以及时更正,谢谢大家!
相关文章:

超详细讲解字符串查找函数(保姆级教程!!!)
超详细讲解字符串查找函数(保姆级教程!!!)字符串查找函数strstr函数strstr函数的使用strstr函数的模拟实现strtok函数strtok函数的使用strtok函数的模拟实现strpbrk函数strpbrk函数的使用strpbrk函数的模拟实现strcspn…...

LeetCode-1138. 字母板上的路径【哈希表,字符串】
LeetCode-1138. 字母板上的路径【哈希表,字符串】题目描述:解题思路一:首先考虑坐标位置,字符是有序的从0开始,当前字符c的行为(c-a)/5,列为(c-a)%5。其次是考虑特殊情况z。若当前从‘z’开始则只能往上走;若是其他字符…...
Vue 可配置化的路由缓存(Vu2 Vue3)
Vue 可配置化的路由缓存(Vu2 & Vue3) 1 介绍 在Vue的项目当中,路由缓存是一个比较常见的功能,譬如,从列表页面进入到详情页面,返回到列表页面时,如果可以保持列表的状态,那用户…...
Linux VPU驱动
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 概述 VPU 是用来进行图像、视频数据进行硬件编、解码的硬件模块。内部集成了 Encoder、Decoder 功能部件进行图像、视频数据进行硬件编、解码&a…...

spring 笔记
一、spring概述 1.1 spring介绍 spring是一个轻量级的控制反转和面向切面的容器框架,用来解决企业项目开发的复杂度问题---解耦 轻量级:体积小,对代码没有侵入性控制反转:IOC inverse of control, 把创建对象的工作交…...
Java日志框架学习
首先,Java日志框架可以分为两类:门面型日志框架和记录型日志框架。 门面型日志框架 JCL:Java日志接口,后更名为Commons LoggingSLF4J:是一套简易Java日志门面,本身并无日志的实现 记录型日志框架 JUL&a…...

基础面试题:堆和栈的区别
面试题:堆和栈的区别(往往讲的是内存zha) 为什么说访问栈栈比访问堆快些? 目录 一、数据结构中的堆栈 1、数据结构中的堆 1)堆的定义 2)堆的效率 2、 数据结构中的栈 二、内存中的堆栈 1、内存堆的定义…...

(干货教程)在VSCode并使用chatgtp插件编写CC++语言程序
(干货教程)在VSCode并使用chatgtp插件编写CC语言程序 下载并安装VSCODE 第1步,下载VSCODE https://code.visualstudio.com/Download 第2步,安装VSCODE 安装过程较简单,这里省略。 安装好后效果如图:…...

【思维模型】概率思维的价值:找到你的人生算法,实现阶级跃迁!
把同样公平的机会放在放在很多人面前,不同的人生算法,会得到迥然不同的结果。 概率思维是什么? 【ChatGPT】概率思维是一种通过使用数学模型来思考和评估不确定性事件的方法。它通过计算不同可能性的概率来预测事件的结果,并评估风险和机会。 概率思维的价值在于它可以帮…...

SpringBoot + kotlin/java + Mybatis-Plus +Sqlite + Gradle多模块项目
前言 我自己的业务项目,先用kotlinspringboot 搭建, 发现gradle支持kts脚本,于是我就搭建试试。我就选用了最流行的Sqlite内嵌数据库,虽然H2也不错,但是Sqlite才是最流行的。orm框架我还是选择了Mybatis-Plus ,为此中…...

Docker 容器与容器云读书笔记(一)
最近都没时间看书,闲暇之余看看书,写写笔记,记录一下这难得的时光。 docker容器的出现 2013年初, 一个名字从云计算领域横空出世,并在整个IT行业激起千层浪,这就是Docker。Docker选择容器作为核心和基础&…...

软件设计(九)
软件设计(八)https://blog.csdn.net/ke1ying/article/details/128954569?spm1001.2014.3001.5501 81、模块A将学生信息,即学生姓名、学号、手机等放到一个结构体系中,传递给模块B,模块A和B之间的耦合类型为 什么耦合…...

FoveaBox原理与代码解析
paper:FoveaBox: Beyond Anchor-based Object Detectorcode:https://github.com/taokong/FoveaBox背景基于anchor的检测模型需要仔细设计anchor,常用方法之一是根据特定数据集的统计结果确定anchor的number、scale、ratio等,但这种…...
Linux内核启动(1,0.11版本)启动BIOS与加载内核
从电源到启动BIOS 从我们按下启动电源到BIOS,按下电源–>主板会向电源组发出信号–> 接受到信号后,当主板收到电源正常启动信号后,主板会启动CPU(CPU重置所有寄存器数据,并且初始化数据),比如32位系统ÿ…...

python制作贪吃蛇小游戏,畅玩无限制
前言 大家早好、午好、晚好吖 ❤ ~ 现在这年头,无论玩个什么游戏都有健康机制, 这让我们愉悦玩游戏得步伐变得承重起来, 于是无聊之下我写了个贪吃蛇小游戏,来玩个快乐 代码展示 导入模块 import random import sys import …...

MySQL-InnoDB数据页结构浅析
在MySQL-InnoDB行格式浅析中,们简单提了一下 页 的概念,它是 InnoDB 管理存储空间的基本单位,一个页的大小一般是 16KB 。 InnoDB 为了不同的目的而设计了许多种不同类型的 页: 存放表空间头部信息的页存放 Insert Buffer信息的…...

Java、JSP职工人事管理系统设计与实现
技术:Java、JSP等摘要:现在随着我们这个社会的计算机技术的快速发展,计算机在企业管理中得到普遍的应用,现在我们利用计算机在实现企业职工的管理越来越重要。当今社会是快速发展的信息社会,自动化信息的作用也变得越来…...

数据结构与算法这么难,为什么我们还要学习?
文章目录前言1. 数据结构与算法是什么?2. 为什么数据结构与算法很难?3. 如何系统学习数据结构与算法?🍑 复杂度🍑 线性表🍑 树形结构🍑 图🍑 排序🍑 字符串🍑…...

剑指 Offer 52. 两个链表的第一个公共节点
摘要 剑指 Offer 52. 两个链表的第一个公共节点 一、双指针解法 使用双指针的方法,可以将空间复杂度降至 O(1)。只有当链表 headA headB都不为空时,两个链表才可能相交。因此首先判断链表 headA和 headB是否为空,如果其中至少有一个链表为…...

可以写进简历的软件测试电商项目,不进来get一下?
前言 说实话,在找项目的过程中,我下载过(甚至付费下载过)N多个项目、联系过很多项目的作者,但是绝大部分项目,在我看来,并不适合你拿来练习,它们或多或少都存在着“问题”ÿ…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...