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

​【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的博客喔&#xff0c;本期系列为​【C语言】长篇详解&#xff0c;字符系列篇3-----strstr&#xff0c;strtok&#xff0c;strerror字符串函数的使用【图文详解​】&#xff0c;图文讲解各种字符串函数&#xff0c;带大家更深刻理解C语言中各种字符串函数的应用&am…...

如何实现一个K8S DevicePlugin?

什么是device plugin k8s允许限制容器对资源的使用&#xff0c;比如CPU和内存&#xff0c;并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时&#xff0c;就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架&#xff0c;你可以用…...

Android LruCache源码分析

文章目录 Android LruCache源码分析概述LruCache和LinkedHashMap关系源码分析属性写入数据读取数据删除缓存 Android LruCache源码分析 概述 LruCache&#xff08;Least Recently Used Cache&#xff0c;最近最少使用缓存&#xff09;是 Android 中的一种缓存机制。 根据数据…...

如何使用Inno Setup制作Unity构建程序的Windows安装程序

1. 准备 &#xff08;1&#xff09;准备好Unity构建的程序集合 必须包括&#xff1a; Data文件夹&#xff08;xxx_Data&#xff09; Mono文件夹&#xff08;MonoBleedingEdge&#xff09; 打包的应用程序文件&#xff08;xxx.exe&#xff09; Unity播放器dll文件&#xff…...

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.确定拓展板的引脚分布情况 第一步&#xff1a;逻辑分析仪j基本操作 1.数据捕捉需要先进行对应软件安装,并按照需求进行配置 2.这里以A20为例:此手机使用显示驱动芯片CST148,触摸屏分辨…...

ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略

文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接&#xff1a; ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件&#xff0c;适用于 Li…...

2024-2-22 作业

作业要求&#xff1a; 复习前面知识点(指针、结构体、函数)整理思维导图顺序表(按位置插入、按位置删除和去重、重新写)理解链表的代码&#xff0c;尝试写一下链表的尾插和输出 1.复习前面知识点(指针、结构体、函数) 2.整理思维导图 3.顺序表(按位置插入、按位置删除和去重、…...

2.1 RK3399项目开发实录-升级固件介绍(物联技术666)

1. 介绍 1.1. 前言 AIO-3399J 出厂默认安装Android操作系统&#xff0c;如果用户要运行其他操作系统&#xff0c;需要使用对应的固件烧写到主板。 AIO-3399J 有灵活的启动方式。一般情况下&#xff0c;除非硬件损坏&#xff0c;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 贪心算法

引入——关于贪心算法 我们先来做一个小游戏——现在假设自己是一个小偷&#xff0c;桌上有一些物品&#xff0c;包括一台iPhone15、一个充电宝、一个眼罩和一个溜溜梅。此时&#xff0c;你听说警察即将到来&#xff0c;那么你会先带走哪个东西呢&#xff1f; 一般来讲&#xf…...

判断当前shell版本

查看$SHELL环境变量&#xff1a; echo $SHELL输出的结果将是当前使用的shell的路径。例如&#xff0c;如果输出为 /bin/bash&#xff0c;则表示当前使用的是Bash shell。 查看ps命令输出&#xff1a; ps -p $$上述命令将显示当前终端进程的信息&#xff0c;其中 $$ 代表当前进…...

如何实现两个电脑之间通过以太网(网线)实现文件互传

如何实现两个电脑之间通过以太网&#xff08;网线&#xff09;实现文件互传 本帖目的&#xff1a;介绍如何通过以太网&#xff08;网线&#xff09;连接两台电脑&#xff0c;通过文件夹共享的方式&#xff0c;实现两台电脑之间的文件互传。 本帖以笔者实际工作上遇到的场景为例…...

Jenkins 中部署Nodejs插件并使用,并构建前端项目(3)

遇到多个版本nodeJS需要构建的时候 1、第一种就是一个配置安装&#xff0c;然后进行选中配置 2、第二种就是插件&#xff1a;nvm-wrapper&#xff0c;我们还是选用NodeJS插件&#xff1a; &#xff08;1&#xff09;可以加载任意npmrc文件&#xff1b; &#xff08;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网络请求封装

网络请求封装 网络请求模块难度较大&#xff0c;如果学习起来感觉吃力&#xff0c;可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API&#xff0c;如 wx.request()&#xff0c;wx.login() 等。这类 API 接口…...

通义千问Qwen-7B-Chat Windows本地部署教程-详细认真版

通义千问本地部署教程&#x1f680; 本专栏的第四弹&#xff0c;在实现了联网调用通义千问模型进行多轮对话&#xff0c;流式输出&#xff0c;以及结合LangChain实现自建知识库之后&#xff0c;开始准备考虑实现对大模型进行本地部署&#xff0c;网上找不到看着比较舒服的教程&…...

探索C语言位段的秘密

位段 1. 什么是位段2. 位段的内存分配3. 位段的跨平台问题4. 位段的应用4. 使用位段的注意事项 1. 什么是位段 我们使用结构体实现位段&#xff0c;位段的声明和结构体是类似的&#xff0c;有两个不同&#xff1a; 位段的成员必须是int&#xff0c;unsigned int&#xff0c;或…...

数据库-数据库设计-社交关系

佛 每有一个新方案&#xff0c;就要考虑有什么影响增删改查可扩展性 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 摘要&#xff1a;视觉transformer由于其高模型能力而取得了巨大的成功。然而&#xff0c;它们卓越的性能伴随着沉重的计算成本&#xff0c;这使得它们不适合实时应用。在这篇论文中&#x…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...