c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客
今天接着来介绍一些:
目录
一.字符串查找
1.strstr()
1.1示例
1.2注意事项:
1.3模拟实现
2.strtok()
2.1示例
2.2注意事项
二.错误信息报告
1.strerror()
1.1示例
1.2注意事项:
三.内存操作函数
1.memcpy()
1.1示例
1.2注意事项
2.memmove()
2.1示例
2.2注意事项:
3.memset()
3.1示例
3.2注意事项:
4.memcmp()
4.1示例
4.2注意事项:
一.字符串查找
1.strstr()
strstr
是一个C标准库函数,用于在一个字符串中查找另一个字符串的第一次出现的位置。它的原型如下:
char *strstr(const char *haystack, const char *needle);
strstr
函数接受两个参数,haystack
是要搜索的字符串,needle
是要查找的子字符串。函数返回一个指向第一次出现的子字符串的指针,如果找不到子字符串,则返回NULL
下面是strstr
函数的工作原理:
-
首先,
strstr
函数会在haystack
字符串中搜索needle
字符串的第一个字符 -
一旦找到了与
needle
的第一个字符匹配的字符,strstr
函数会继续比较haystack
中的后续字符和needle
中的字符,直到找到一个不匹配的字符或者needle
中的所有字符都匹配 -
如果找到了完全匹配的子字符串,
strstr
函数会返回指向该子字符串的指针 -
如果在
haystack
中找不到子字符串,或者needle
是一个空字符串,则strstr
函数会返回NULL
1.1示例
int main()
{char arr1[] = "abcdef";char arr2[] = "cd";printf("%s", strstr(arr1, arr2));return 0;
}
如果找到了完全匹配的子字符串,strstr
函数会返回指向该子字符串的指针,结果如下:
1.2注意事项:
strstr
函数是区分大小写的,如果要进行大小写不敏感的字符串比较,可以使用其他函数
1.3模拟实现
char* my_strstr(const char* a1, const char* a2)
{char* cp = a1;char* str1 = a1;char* str2;while (*cp){str1 = cp;str2 = a2;while (*str1&&*str2&&*str1 == *str2){str1++;str2++;}if (*str2 == '\0'){return cp;}cp++;}return NULL;
}int main()
{char arr1[] = "abcdef";char arr2[] = "cd";printf("%s", my_strstr(arr1, arr2));return 0;
}
2.strtok()
strtok
是一个C标准库函数,用于将一个字符串分割成多个子字符串。它的原型如下:
char * strtok (char *str , const char *delim);
其中,str
是要分割的字符串,delim
是用作分隔符的字符串。函数返回一个指向分割后的第一个子字符串的指针,如果没有更多的子字符串,则返回NULL
。
strtok
函数使用一个静态变量来保存当前的分割位置,因此在多次调用strtok
时,需要将原始字符串传递给第一次调用,而后续的调用只需要传递NULL
作为第一个参数
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
2.1示例
int main()
{char arr[] = "123@abc%ABC";char a[] = "@%";printf("%s\n", strtok(arr, a));/*printf("%s\n", strtok(NULL, a));*/return 0;
}
结果如下:
int main()
{char arr[] = "123@abc%ABC";char a[] = "@%";printf("%s\n", strtok(arr, a));printf("%s\n", strtok(NULL, a));printf("%s\n", strtok(NULL, a));return 0;
}
结果如下:
充分利用性质可以写出这样的代码:
int main() {char arr[] = "123@abc%ABC";char a[] = "@%";/*printf("%s\n", strtok(arr, a));printf("%s\n", strtok(NULL, a));printf("%s\n", strtok(NULL, a));*/for (char* ret = strtok(arr, a); ret != NULL;ret= strtok(NULL, a)){printf("%s\n", ret);}return 0; }
2.2注意事项
需要注意的是,
strtok
函数会修改原始字符串,将分隔符替换为NULL
字符。如果需要保留原始字符串,可以使用副本进行分割操作
二.错误信息报告
1.strerror()
strerror
是一个C标准库函数,用于将错误码转换为对应的错误信息字符串。它的原型如下:
char * strerror( int errnum );
其中,errnum
是错误码。函数返回一个指向错误信息字符串的指针
errnum
是一个整数类型的错误码,通常用于表示函数调用或操作的结果状态errno
是一个全局变量,用于存储最近一次发生的错误码。当函数调用或操作失败时,它们通常会设置errno
为一个非零的错误码,以指示错误的类型
1.1示例
输出1~10分别代表的错误信息:
int main()
{for (int i = 1; i <= 10; i++){printf("%s\n", strerror(i));}return 0;
}
结果如下:
1.2注意事项:
strerror
函数返回的指针指向的是一个静态分配的字符串,因此在多线程环境下不是线程安全的
三.内存操作函数
1.memcpy()
memcpy
是一个标准C库函数,用于将一段内存区域的数据复制到另一段内存区域。它的函数原型如下:
void *memcpy(void *dest, const void *src, size_t n);
其中,dest
是目标内存区域的指针,src
是源内存区域的指针,n
是要复制的字节数。
memcpy
函数将源内存区域的前n
个字节复制到目标内存区域中。如果源和目标区域重叠,memcpy
函数的行为是未定义的。如果需要处理重叠区域的复制,可以使用memmove
函数(下面介绍)
这个函数在遇到 '\0' 的时候并不会停下来
1.1示例
int main()
{char src[] = "Hello, world!";char dest[20];memcpy(dest, src, strlen(src) + 1);printf("source string: %s\n", src);printf("copied string: %s\n", dest);return 0;
}
结果如下:
1.2注意事项
需要注意的是,
memcpy
函数不会自动添加字符串结束符\0
,因此在复制字符串时需要将\0
一起复制。在上面的示例中,strlen(src) + 1
计算了源字符串的长度,并将其加1,以便复制\0
2.memmove()
memmove
是一个标准C库函数,用于将一段内存区域的数据复制到另一段内存区域,与memcpy
函数类似。但是,memmove
函数可以处理源和目标区域重叠的情况,而memcpy
函数则不能
memmove
函数的函数原型如下:
void *memmove(void *dest, const void *src, size_t n);
其中,dest
是目标内存区域的指针,src
是源内存区域的指针,n
是要复制的字节数。
memmove
函数将源内存区域的前n
个字节复制到目标内存区域中。如果源和目标区域重叠,memmove
函数会确保复制的结果是正确的,即使源和目标区域重叠。因此,memmove
函数比memcpy
函数更安全,但通常也更慢
2.1示例
int main()
{char str[] = "123456";memmove(str,str+3,3);printf("%s\n", str);return 0;
}
结果如下:
2.2注意事项:
需要注意的是,
memmove
函数和memcpy
函数一样,不会自动添加字符串结束符\0
,因此在复制字符串时需要将\0
一起复制
3.memset()
memset
是一个用于设置内存块内容的函数。它可以将指定的内存块中的每个字节都设置为特定的值。
memset
函数的原型如下:
void *memset(void *ptr, int value, size_t num);
参数说明:
ptr
:指向要设置的内存块的指针。value
:要设置的值,以整数形式提供。num
:要设置的字节数。
memset
函数将ptr
指向的内存块的前num
个字节设置为value
指定的值
3.1示例
int main()
{char str[20] = { 0 };memset(str, 'A', 10);printf("%s\n", str);return 0;
}
结果如下:
3.2注意事项:
需要注意的是,
memset
函数是按字节进行设置的,因此对于非字符类型的数组,需要将value
参数转换为相应的字节表示
4.memcmp()
memcmp
函数用于比较两个内存区域的内容是否相同,其原型如下:
int memcmp(const void *ptr1, const void *ptr2, size_t num);
参数说明:
ptr1
:指向第一个内存区域的指针。ptr2
:指向第二个内存区域的指针。num
:要比较的字节数。
memcmp
函数将ptr1
指向的内存区域和ptr2
指向的内存区域的前num
个字节进行比较,返回值如下:
- 如果两个内存区域相同,返回0。
- 如果第一个内存区域小于第二个内存区域,返回负整数。
- 如果第一个内存区域大于第二个内存区域,返回正整数
4.1示例
int main()
{char str1[20] = "Hello, world!";char str2[20] = "Hello, world!";int result1 = memcmp(str1, str2, strlen(str1));printf("result = %d\n", result1);return 0;
}
结果如下:
4.2注意事项:
memcmp
函数比较的是字节,因此对于非字符类型的数组,比较的结果可能与预期不同
好了各位,这次的内容就先整理到这里吧!下次按照学习计划就打了结构体的部分知识内容啦!
相关文章:

c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些&#x…...

一文看懂光模块的工作原理
你们好,我的网工朋友 光模块有很多类别,是我们经常要用到的PHY层器件。虽然封装,速率,传输距离有所不同,但是其内部组成基本是一致的。 以太网交换机常用的光模块有SFP,GBIC,XFP,X…...

基于SpringBoot的桂林旅游景点导游平台
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 景点类型管理 景点信息管理 线路推荐管理 用户注册 线路推荐 论坛交流 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...

【小程序 - 加强】自定义组件、使用npm包、全局数据共享、分包_05
目录 一、自定义组件 1. 组件的创建与引用 1.1 创建组件 1.2 引用组件 1.2.1 局部引用组件 1.2.2 全局引用组件 1.2.3 全局引用 VS 局部引用 1.2.4 组件和页面的区别 2. 样式 2.1 组件样式隔离 2.2 组件样式隔离的注意点 2.3 修改组件的样式隔离选项 2.4 styleIso…...

Vue.js3学习篇--Vue模板应用
目录 一,模板基础 1.模板插值 (1)基础插值 (2)HTML代码插值 (3)标签属性插值 2.模板指令 (1)定义 (2)指令参数 二.条件渲染 1.使用v-if指令渲染 2.使…...

【软考】5.2 传输介质/通信方式/IP地址/子网划分
《传输介质》 双绞线:网线;传输距离在100m以内 无屏蔽双绞线:UTP;可靠性相对较低屏蔽双绞线:STP;屏蔽怕干扰;可靠性相对较高;一般用于对传输可靠性要求很高的场合 网线:…...

软件测试银行项目网上支付接口调用测试实例
公司最近有一个网站商城项目要开始开发了,这几天老板和几个同事一起开着需求会议, 讨论了接下来的业务规划和需求策略,等技术需求一下来还要讨论技术需求, 确认后再慢慢的进入开发阶段,趁着闲暇时间新造的人想总结一…...
w806 adc 中断扫描通道采集
用到了该芯片adc 扫描4个adc 通道,官方的死循环等待非常浪费时间,这里改用adc 中断采集方式,记录一下 int32_t adcFilterSum[4]{0}; int32_t detec_adc_value[4]{0};//mV int16_t detec_convt_ok[4]{0};/*is OK*/ ADC_HandleTypeDef hadc;vo…...
使用CSS的Positions布局打造响应式网页
在当今移动互联网的时代,响应式网页设计已经成为了一个必备的技能。通过使用CSS Positions布局,我们可以轻松地实现一个响应式的网页,使网页能够在不同的屏幕尺寸下自动适应。本文将介绍如何使用CSS Positions布局来打造一个响应式网页&#…...

模型训练环境相关(CUDA、PyTorch)
模型训练环境相关(CUDA、PyTorch) 1. 查看当前 GPU 所能支持的最高版本的 CUDA2. 如何判断是否安装了 CUDA3. 安装 PyTorch3.1 创建虚拟环境3.2 激活并进入虚拟环境3.3 安装 PyTorch 1. 查看当前 GPU 所能支持的最高版本的 CUDA 打开 NVIDIA 控制面板&a…...
链动2+1模式:社交电商行业的新型商业模式与营销手段
链动21模式是近年来在社交电商行业中崭露头角的一种新型商业模式和营销手段。在经历了多年的发展之后,社交电商行业已经进入了一个竞争激烈、用户获取成本高昂的阶段。在这个阶段,如何迅速吸引用户并增加他们的留存率和复购率成为了亟待解决的问题。 为了…...

竞赛选题 深度学习 opencv python 实现中国交通标志识别
文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 🔥 优质…...
LuatOS-SOC接口文档(air780E)-- fskv - kv数据库,掉电不丢数据
示例 -- 本库的目标是替代fdb库 -- 1. 兼容fdb的函数 -- 2. 使用fdb的flash空间,启用时也会替代fdb库 -- 3. 功能上与EEPROM是类似的 fskv.init() fskv.set("wendal", 1234) log.info("fskv", "wendal", fskv.get("wendal"))--[[ fs…...

一篇文章教你Pytest快速入门和基础讲解,一定要看!
前言 目前有两种纯测试的测试框架,pytest和unittestunittest应该是广为人知,而且也是老框架了,很多人都用来做自动化,无论是UI还是接口pytest是基于unittest开发的另一款更高级更好用的单元测试框架出去面试也好,跟别…...

SpringBoot项目:Cannot find declaration to go to
SpringBoot项目get,set方法总报Cannot find declaration to go to 搜了很多答案,没解决 后来仔细一想,原来是我的idea软件重装了,lombok插件没重新安装导致。 安装步骤: 1、下载地址:https://plugins.jetbrains.com…...
【高并发】多线程和高并发提纲
文章目录 三大源头两个主要问题三大解决方案 最近正在面试,对多线程和高并发相关问题整理了一个简单的提纲。 个人感觉这三大部分由底向上,足够引出对并发编程中大部分问题的讨论~ 三大源头 线程切换带来的原子性问题。 原子操作:利用CPU提…...

vue.js处理数组对象中某个字段是否变为两个字段
一、场景: 产品要求做一个时间步骤条,使用目前后端已返回的数据进行操作实现。时间步骤条要求日期和时间分开显示且相同日期只显示第一个日期。 图左边为实现效果,右边为后台返回的接口。接口中current字段表示当前到达第几步,从…...
从零开始的C++(补充三的内容)
auto:在编译阶段根据数据的类型确认auto所代表的类型,并将auto换成对应的类型。 特点: 1、auto所能代表的类型必须是在编译阶段就能确认的。 2、auto修饰的变量必须初始化,否则编译器无法判断auto的实际类型。 3、auto会根据第一个数据来…...

微信小程序通过createSelectorQuery获取元素 高度,宽度与界面距离
小程序官方有提供给我们一个 const query wx.createSelectorQuery() 函数 我们可以先编写这样一段代码 wxml <view><button bindtap"getDom">点击查看</button><view class "textIn" style "height: 100px;width: 30px;&quo…...
MySQL-事务
MySQL-事务 1.什么是事务 举例:想象炒菜的过程。 洗菜切菜炒菜装盘 我相信缺少任何任何一个步骤,都不完美!!!可以将炒菜的过程理解为一个事务,是一组操作的集合,而MySQL中的事务也是如此。但…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...