【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】
欢迎来CILMY23的博客喔,本期系列为【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】,图文讲解各种字符串函数,带大家更深刻理解C语言中各种字符串函数的应用,感谢观看,支持的可以给个赞哇。
前言
上一篇说到,有不受长度限制的字符串函数,它们分别是strcpy,strcat,strcmp,为了方便我们想要长度限制,C语言提供了三个加n的函数,strncpy,strncat,strncmp函数,本期将了解剩下的三个字符串函数,它们分别是strstr,strtok,strerror。
目录
一、strstr
二、strtok
三、strerror
一、strstr
strstr函数可以在cplusplus中查到,strstr - C++ Reference (cplusplus.com)
函数原型如下:
const char * strstr ( const char * str1, const char * str2 );char * strstr ( char * str1, const char * str2 );
函数介绍如下:

返回值和使用案例:

strstr的使用
strstr函数功能就是返回str2在str1中第一次出现的位置,如果str2没有在str1中出现,就返回NULL
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "hello CILMY23";char arr2[] = "C";char* ret = strstr(arr1, arr2);if (ret != NULL)printf("%s \n", ret);elseprintf("找不到\n");ret = strstr(arr2, arr1);if (ret != NULL)printf("%s \n", ret);elseprintf("找不到\n");return 0;
}
结果如下:

strstr的模拟实现
为了检验自己写的是否对不对,我们拿出几组的测试用例
void Judge(char* p)
{if (p != NULL)printf("%s \n", p);elseprintf("找不到\n");
}int main()
{char arr1[] = "hello CILMY23";char arr2[] = "C";char arr3[] = "lllC";char arr4[] = "This is a simple string";char arr5[] = "";char* ret = strstr(arr1, arr2);Judge(ret);ret = strstr(arr2, arr1);Judge(ret);ret = strstr(arr3, arr1);Judge(ret);ret = strstr(arr3, arr2);Judge(ret);ret = strstr(arr1, arr3);Judge(ret);ret = strstr(arr2, arr3);Judge(ret);ret = strstr(arr4, "simple");Judge(ret);ret = strstr(arr1, arr5);Judge(ret);return 0;
}
这组测试用例的结果是:

思路一
思路解析:
遍历源字符串,找到与字符串2首字母相同的字符,进入循环2,但在进入之前需要保存一份当前位置,然后我们再去利用新开辟出来的两个指针去遍历两个字符串,如果有不相等的地方,那么字符串肯定是走不到尾巴的,也就是不可能等于'\0',此时继续遍历字符串1,直到字符串1遍历结束,完成整个字符串的查找,没有就返回NULL。
char * my_strstr(const char* str1,const char* str2)
{assert(str1 && str2);char* str3 = NULL;char* str4 = NULL;while (*str1 != '\0'){ str4 = str2;str3 = str1;while(*str3 == *str4 && *str3 && *str4){str3++;str4++;}if (*str4 == '\0')return str1;str1++;}return NULL;
}
逻辑图如下:

代码优化
代码优化解析:
1.我们并不希望在遍历字符串的时候所有的值都被修改,包括我后续返回的地址,所以全部都可以用const修饰
2.当我第二个字符串为空的时候,返回字符串1的地址,就相当于你让我在一个字符串里找什么都没有的东西,库里设计是返回第一个字符串地址
3.我们不希望改变原有的地址,str1,和str2,所以再创建一个指针变量用来代替上述str1的使用
const char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* cp = str1;const char* s1 = NULL;const char* s2 = NULL;if (*str2 == '\0'){return str1;}while (*cp){s1 = cp;s2 = str2;while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0'){s1++;s2++;}if (*s2 == '\0'){return cp;}cp++;}return NULL;
}
根据测试用例跑出来的结果如下:

二、strtok
了解strtok函数之前,我们要先了解一个概念,相信大家都看过IP地址, 计算机网络通信协议是用的IP协议,于是链接进互联网的设备会有一个IP地址,这个IP地址,IP地址通常用“点分十进制”表示成(a.b.c.d)的形式
例如:192.168.1.23
IP地址的本质还是一个整数,因为不好记,才有了点分十进制的表示方式。
那如果我们想把这个IP地址的每个数字取出来就会用到,strtok这个函数。又或者你想把邮箱的域名,邮箱名,域名后缀取出来也会用到strtok这个函数。其中@和.这种东西我们就把它称作分隔符
strtok网站以及函数原型如下:
strtok - C++ Reference (cplusplus.com)
char * strtok ( char * str, const char * delimiters );
strtok的函数介绍:

返回值和使用案例:

strtok的使用
#include<stdio.h>
#include<string.h>int main()
{char str1[] = "hello.CIL.MY@23";char buf[60] = { 0 };strcpy(buf, str1);char* p = ".@";char* r = NULL;for (r = strtok(buf, p); r != NULL; r = strtok(NULL, p)){printf("%s", r);}return 0;
}
打印结果如下:

strtok总结:
• sep参数指向⼀个字符串,定义了用作分隔符的字符集合
• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记
• strtok函数找到str中的下⼀个标记,并将其用\0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。)
• strtok函数的第⼀个参数不为NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
• strtok函数的第⼀个参数为NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
• 如果字符串中不存在更多的标记,则返回NULL 指针。
三、strerror
strerror 的网址:
strerror - C++ Reference (cplusplus.com)
函数原型:
char * strerror ( int errnum );
函数介绍如下:

函数的功能及使用案例:

函数解析:
strerror是一个返回错误码所对应的错误字符串的起始地址,在C语言的库函数中设计错误码,当我们库函数在调用过程中发生错误信息了,要记录下来,这就是错误码。是一个编码。
当库函数调用失败的时候,会将错误码记录到变量errno当中,errno是C语言中的一个全局变量。
strerror的使用
int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%d:%s \n",i,strerror(i));}return 0;
}
结果如下:
相关文章:
【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】
欢迎来CILMY23的博客喔,本期系列为【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解】,图文讲解各种字符串函数,带大家更深刻理解C语言中各种字符串函数的应用&am…...
如何实现一个K8S DevicePlugin?
什么是device plugin k8s允许限制容器对资源的使用,比如CPU和内存,并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时,就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架,你可以用…...
Android LruCache源码分析
文章目录 Android LruCache源码分析概述LruCache和LinkedHashMap关系源码分析属性写入数据读取数据删除缓存 Android LruCache源码分析 概述 LruCache(Least Recently Used Cache,最近最少使用缓存)是 Android 中的一种缓存机制。 根据数据…...
如何使用Inno Setup制作Unity构建程序的Windows安装程序
1. 准备 (1)准备好Unity构建的程序集合 必须包括: Data文件夹(xxx_Data) Mono文件夹(MonoBleedingEdge) 打包的应用程序文件(xxx.exe) Unity播放器dll文件ÿ…...
linux 面试题
1.linux操作系统的常用指令可以详细说下吗,平常哪些用的比较多 文件目录操作命令: ls cd more cat tail mkdir touch rm rmdir 拷贝复制: cp mv 打包解包压缩解压: tar -z 解亚压缩 -c 打包 -x 解包 -v 显示过程 -f 指定文件名 文本编辑: vi vim 查找: find 查找文件 gre…...
嵌入式中逻辑分析仪基本操作方法
前期准备 1.一块能触摸的屏对应的主板机 2.逻辑分析仪对应的软件工具 3.对应的拓展板 4.确定拓展板的引脚分布情况 第一步:逻辑分析仪j基本操作 1.数据捕捉需要先进行对应软件安装,并按照需求进行配置 2.这里以A20为例:此手机使用显示驱动芯片CST148,触摸屏分辨…...
ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略
文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接: ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件,适用于 Li…...
2024-2-22 作业
作业要求: 复习前面知识点(指针、结构体、函数)整理思维导图顺序表(按位置插入、按位置删除和去重、重新写)理解链表的代码,尝试写一下链表的尾插和输出 1.复习前面知识点(指针、结构体、函数) 2.整理思维导图 3.顺序表(按位置插入、按位置删除和去重、…...
2.1 RK3399项目开发实录-升级固件介绍(物联技术666)
1. 介绍 1.1. 前言 AIO-3399J 出厂默认安装Android操作系统,如果用户要运行其他操作系统,需要使用对应的固件烧写到主板。 AIO-3399J 有灵活的启动方式。一般情况下,除非硬件损坏,AIO-3399J 开发板是不会变砖的。 如果在升级过…...
Uniapp + VUE3.0 实现双向滑块视频裁剪效果
效果图 <template><view v-if"info" class"all"><video:src"info.videoUrl"class"video" id"video" :controls"true" object-fit"fill" :show-fullscreen-btn"false"play-btn…...
【算法小讲堂】#1 贪心算法
引入——关于贪心算法 我们先来做一个小游戏——现在假设自己是一个小偷,桌上有一些物品,包括一台iPhone15、一个充电宝、一个眼罩和一个溜溜梅。此时,你听说警察即将到来,那么你会先带走哪个东西呢? 一般来讲…...
判断当前shell版本
查看$SHELL环境变量: echo $SHELL输出的结果将是当前使用的shell的路径。例如,如果输出为 /bin/bash,则表示当前使用的是Bash shell。 查看ps命令输出: ps -p $$上述命令将显示当前终端进程的信息,其中 $$ 代表当前进…...
如何实现两个电脑之间通过以太网(网线)实现文件互传
如何实现两个电脑之间通过以太网(网线)实现文件互传 本帖目的:介绍如何通过以太网(网线)连接两台电脑,通过文件夹共享的方式,实现两台电脑之间的文件互传。 本帖以笔者实际工作上遇到的场景为例…...
Jenkins 中部署Nodejs插件并使用,并构建前端项目(3)
遇到多个版本nodeJS需要构建的时候 1、第一种就是一个配置安装,然后进行选中配置 2、第二种就是插件:nvm-wrapper,我们还是选用NodeJS插件: (1)可以加载任意npmrc文件; (2&#x…...
VUE为什么有的属性要加冒号
<el-menu-item :index "/item.menuClick" v-for"(item,i) in menu"><i class"item.menuIcon" ></i><span slot"title">{{item.menuName}}</span></el-menu-item>不加不行 加了好像是吧整体作为…...
微信小程序 --- wx.request网络请求封装
网络请求封装 网络请求模块难度较大,如果学习起来感觉吃力,可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API,如 wx.request(),wx.login() 等。这类 API 接口…...
通义千问Qwen-7B-Chat Windows本地部署教程-详细认真版
通义千问本地部署教程🚀 本专栏的第四弹,在实现了联网调用通义千问模型进行多轮对话,流式输出,以及结合LangChain实现自建知识库之后,开始准备考虑实现对大模型进行本地部署,网上找不到看着比较舒服的教程&…...
探索C语言位段的秘密
位段 1. 什么是位段2. 位段的内存分配3. 位段的跨平台问题4. 位段的应用4. 使用位段的注意事项 1. 什么是位段 我们使用结构体实现位段,位段的声明和结构体是类似的,有两个不同: 位段的成员必须是int,unsigned int,或…...
数据库-数据库设计-社交关系
佛 每有一个新方案,就要考虑有什么影响增删改查可扩展性 MySQL 根据ER图设计表 create table follow(id bigint unsigned not null auto_increment comment 主键,gmt_create datetime null default current_timestamp,gmt_modified null default current_timest…...
YOLO算法改进Backbone系列之:EfficientViT
EfficientViT: Memory Effificient Vision Transformer with Cascaded Group Attention 摘要:视觉transformer由于其高模型能力而取得了巨大的成功。然而,它们卓越的性能伴随着沉重的计算成本,这使得它们不适合实时应用。在这篇论文中&#x…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
