超详细讲解字符串查找函数(保姆级教程!!!)
超详细讲解字符串查找函数(保姆级教程!!!)
- 字符串查找函数
- 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多个项目、联系过很多项目的作者,但是绝大部分项目,在我看来,并不适合你拿来练习,它们或多或少都存在着“问题”ÿ…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...