超详细讲解字符串查找函数(保姆级教程!!!)
超详细讲解字符串查找函数(保姆级教程!!!)
- 字符串查找函数
- 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多个项目、联系过很多项目的作者,但是绝大部分项目,在我看来,并不适合你拿来练习,它们或多或少都存在着“问题”ÿ…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
