【C语言 模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数】
C语言程序设计笔记---026
- C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数
- 1、介绍strncpy函数
- 1.1、模拟实现strncpy函数
- 2、介绍strncat函数
- 2.1、模拟实现strncat函数
- 3、介绍strncmp函数
- 3.1、模拟实现strncmp函数
- 4、介绍strstr函数
- 4.1、模拟实现strstr函数
- 5、结语
C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数
前言:
通过C语言字符串函数的知识,这篇将对strncpy、strncat、strncmp函数进行深入学习底层原理的知识,并模拟实现对应功能。
/知识点汇总/
长度不受限制的字符串函数:strcat,strcmp,strcpy
介绍长度受限制字符串函数:strncat,strncmp,strncpy
字符串查找函数:strstr
1、介绍strncpy函数
函数原型:char* strncpy(char* strDest, const char* strSource, size_t count);
函数功能:完成源字符串到目标字符串的拷贝,返回目标字符串的起始地址,返回值类型为char*,另外还可指定拷贝的长度
头文件:<string.h>
使用注意事项:
(1)、源字符串必须以’\0’结束(因为会包括’\0’一起拷贝过去)
(2)、拷贝会将源字符串中的’\0’拷贝到目标空间
(3)、目标空间必须足够大,确保能存放源字符串
(4)、目标空间必须可变(不能是常量)
(5)、初始化为数组形式时,空间需要指明合适的大小
示例代码1如下:
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcchar arr1[20] = "xxxxxxxxxxxxxxx";char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcxxxxxxxxxxreturn 0;
}
示例代码2如下:
探讨拷贝长度的因素,当指定的拷贝长度比源字符串长度大时,自动补\0
#include <stdio.h>
#include <string.h>int main()
{char arr1[20] = "xxxxxxxxxxxx";char arr2[] = "abc";strncpy(arr1, arr2, 6);//6长度比str2长时,自动补的'\0'.printf("%s\n", arr1);//abc\0\0\0return 0;
}
1.1、模拟实现strncpy函数
#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* str1, const char* str2, size_t num)
{assert(str1 && str2);char* ret = str1;while (num--){*str1++ = *str2++;}return ret;
}
int main()
{char arr1[] = "abcdef";char arr2[] = "defabc";printf("请输入拷贝的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%s\n", my_strncpy(arr1, arr2,len));return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.num–执行的就是依次拷贝字符串的内容,直到num = 0,从而限制了拷贝个数,最后跳出while循环
2、介绍strncat函数
函数原型:char* strncat(char* strDest, const char* strSource, size_t count);
函数功能:完成源字符串到目标字符串的追加,返回目标字符串的起始地址,返回值类型为char*,另外还可指定追加的长度
头文件:<string.h>
使用注意事项:
(1)、源字符串必须以’\0’结束(因为会包括’\0’一起追加过去)
(2)、追加会将源字符串中的’\0’拷贝到目标空间
(3)、目标空间必须足够大,确保能存放源字符串
(4)、目标空间必须可变(不能是常量)
(5)、初始化为数组形式时,空间需要指明合适的大小
示例代码1如下:
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc";char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);//abcdefreturn 0;
}
示例代码2如下:
探究’\0’的追加情况1
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);//abcdef\0return 0;
}
示例代码3如下:
探究’\0’的追加情况2
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 10);//10长度比str2长时,自动在末尾补'\0'.此函数就不会对超出长度的字符进行操作了printf("%s\n", arr1);//abcdefreturn 0;
}
小结:
①、目标字符串中本身具备’\0’时,依然以’\0’开始覆盖,最后补’\0’结束
②、指定长度长度比源字符串长时,自动在末尾补’\0’,且此函数就不会对超出长度的字符进行操作了
2.1、模拟实现strncat函数
#include <stdio.h>
#include <assert.h>
char* my_strncat(char* str1, const char* str2, size_t num)
{assert(str1 && str2);char* ret = str1;while (*str1 != '\0'){str1++;}//*str1--;while (num--){*str1++ = *str2++;}*str1 = '\0';return ret;
}
int main()
{char arr1[10] = "abc";char arr2[10] = "abc";printf("请输入追加的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%s\n", my_strncat(arr1, arr2, len));return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.str1 != '\0’执行的就是指针遍历目标字符串的内容,直到目标字符串的下一个地址,从而再以num–限制追加的字符长度
4.值得注意的是str1 = ‘\0’,最后需要置结束标志位,否则就是乱码,因为直到遇见’\0’才结束。
3、介绍strncmp函数
函数原型:int strncmp( const char *string1, const char *string2, size_t count );
函数功能:字符串大小比较,返回值类型为int,另外还可指定比较的长度
头文件:<string.h>
示例代码1如下:
#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcqw";int ret = strncmp(arr1, arr2, 3);printf("%d\n", ret);//0int ret2 = strncmp(arr1, arr2, 4);printf("%d\n", ret2);//-1return 0;
}
3.1、模拟实现strncmp函数
#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1,const char* str2, size_t num)
{assert(str1 && str2);while (num && *str1 && *str2){if (*str1 > *str2){return 1;}if (*str1 < *str2){return -1;}num--;str1++;str2++;}return 0;
}
int main()
{char arr1[] = "abcdef";char arr2[] = "defabc";printf("请输入比较的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%d\n", my_strncmp(arr1, arr2,len));return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.num && *str1 && *str2执行的就是依次比较字符串的内容,直到源字符串/目标字符串/指定字符长度 = 0结束,从而限制了比较字符个数,最后跳出while循环
4、介绍strstr函数
函数原型:const char *strstr( const char *string, const char *strCharSet );
函数功能:在字符串中找字符串(字符串中找子字符串或子段)
头文件:<string.h>
返回值:strstr会返回主字符串中子字符串第一次出现的位置,如果主字符串中没有子字符串,则返回NULL
示例代码1如下:
#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdefghi";char arr2[] = "def";char* ret = strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);//defghi}return 0;
}
4.1、模拟实现strstr函数
蛮力法,直接遍历查找
#include <stdio.h>
#include <assert.h>
const char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* cp;//记录开始匹配的位置const char* s1;//遍历str1指向的字符串const char* s2;//遍历str2指向的字符串if (*str2 == '\0')return str1;cp = str1;while (*cp){s1 = cp;s2 = str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
int main()
{char arr1[] = "abcdefghi";char arr2[] = "def";const char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);//defghi}return 0;
}
解释说明:
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.定义三个指针变量,cp用于标记返回的起始地址,s1和s2用于遍历str1和str2逐个比较即可,
3.*s1 && *s2 && *s1 == *s2执行的就是依次比较字符串的内容,直到子字符串与主字符串内容匹配则结束,最后跳出while循环,返回cp的地址。
5、结语
掌握模拟函数的逻辑思维尽可能考虑全面,学会利用画逻辑图分析并一步步的推理
学习函数的最实用的方式就是用自己的逻辑简单实现一些类似的功能
半亩方糖一鉴开,天光云影共徘徊。
问渠哪得清如许?为有源头活水来。–朱熹(观书有感)
相关文章:
【C语言 模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数】
C语言程序设计笔记---026 C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数1、介绍strncpy函数1.1、模拟实现strncpy函数 2、介绍strncat函数2.1、模拟实现strncat函数 3、介绍strncmp函数3.1、模拟实现strncmp函数 4、介绍strstr函数4.1、模拟实现strstr函数…...

Mongodb7启动报错排除解决方案
一: 报错信息: [rootwww log]# journalctl -xe -- Unit mongodb.service has begun starting up. /usr/local/mongodb/mongdb7/bin/mongod --help for more information 10月 03 13:47:39 www.yhchange.com systemd[1]: mongodb.service: control process exited, …...

王杰国庆作业day5
...

QT、C++实现地图导航系统(mapSystem)
文章目录 地图导航系统项目应用背景技术栈选择数据处理算法实现界面实现源码展示成果展示源码下载 (免费) 地图导航系统 项目应用背景 电子地图导航系统的主要目的是为用户提供精确、实时的导航和位置信息,以帮助他们在城市或地区内轻松找到…...

STM32 定时器介绍--通用、高级定时器
目录 高级定时器 1.功能框图 1-时钟源 2-时基单元 3-输入捕获 4-输出比较 2.输入捕获的应用 3.输出比较的应用 4.初始化结构体 1-时基初始化结构体 2-输出比较结构体 3-PWM信号 周期和占空比的计算--以通用定时器为例 4-输入捕获结构体 5-断路和死区初始化结构体…...

淘宝天猫渠道会员购是什么意思?如何开通天猫淘宝渠道会员购有什么用?
淘宝天猫渠道会员购是什么意思? 淘宝天猫渠道会员购与淘宝天猫粉丝福利购意思基本相同,都可以领取淘宝天猫大额内部隐藏优惠券、通过草柴APP开通绑定渠道会员还可以获得购物返利。 草柴APP如何绑定开通淘宝天猫渠道会员? 1、手机下载安装「…...

(Note)机器学习面试题
机器学习 1.两位同事从上海出发前往深圳出差,他们在不同时间出发,搭乘的交通工具也不同,能准确描述两者“上海到深圳”距离差别的是: A.欧式距离 B.余弦距离 C.曼哈顿距离 D.切比雪夫距离 S:D 1. 欧几里得距离 计算公式&#x…...

思科:iOS和iOSXe软件存在漏洞
思科警告说,有人试图利用iOS软件和iOSXe软件中的一个安全缺陷,这些缺陷可能会让一个经过认证的远程攻击者在受影响的系统上实现远程代码执行。 中严重程度的脆弱性被追踪为 CVE-2023-20109 ,并以6.6分得分。它会影响启用Gdoi或G-Ikev2协议的软件的所有版本。 国际知名白帽黑客…...

CCF CSP认证 历年题目自练Day19
题目一 试题编号: 201812-1 试题名称: 小明上学 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 题目背景 小明是汉东省政法大学附属中学的一名学生,他每天都要骑自行车往返于家和学校。为了能尽可能充…...

Java 开发环境配置
在本章节中我们将为大家介绍如何搭建Java开发环境。 目录 window系统安装java 下载JDK 配置环境变量 JAVA_HOME 设置 PATH设置 CLASSPATH 设置 测试JDK是否安装成功 Linux,UNIX,Solaris,FreeBSD环境变量设置 流行 Java 开发工具 使…...
[2023.09.26]: JsValue的转换体验与as关键字的浅析
昨天解决了焦点问题,今天就开始搬砖了。本以为可以一帆风顺,但是还是遇到了几个问题,不过还好,都被一一解决,这里我分享一下JsValue的转换体验以及关键字as的使用浅析。 场景描述 我是在什么情况下遇到JsValue的转换…...

SpringBoot Validation入参校验国际化
在 Spring Boot 中,可以使用 Validation 和国际化来实现对入参的校验。 常用的校验 NotNull验证字段值不能为 nullNotEmpty验证字段值不能为 null 或空字符串NotBlank验证字符串字段值不能为空、null,并且必须至少包含一个非空白字符Size验证字符串、…...

树莓集团涉足直播产业园区运营,成都直播产业园区再添黑马
树莓集团涉足成都直播产业园运营领域,这一消息引起了业界的广泛关注。在这个无限可能的直播领域中,树莓集团将与上市公司德商产投紧密合作,立志为成都直播行业的发展注入新的活力。成都天府蜂巢直播产业园推行着一系列创新的政策措施…...
中小学教师ChatGPT的23种用法
原文:中小学教师ChatGPT的23种用法 近日,ChatGPT引发舆论风暴,火遍全球。作为一款生成式人工智能软件,ChatGPT可以就任何议题生成文本,完成包括回答问题,撰写文章、论文、诗歌在内的多种工作。各界盛赞其“…...

Ubuntu性能分析-ftrace 底层驱动
1、框架介绍 ftrace内核驱动可以分为几部分:ftrace framework,RingBuffer,debugfs,Tracepoint,各种Tracer。 ftrace框架是整个ftrace功能的纽带,包括对内和的修改,Tracer的注册,RingBuffer的控制等等。 RingBuffer是静态动态ftrace的载体。 debugfs则提供了用户空间…...

网盘搜索引擎:点亮知识星空,畅享数字宝藏!
大家好!作为一名资深的网络产品运营人员,我今天要向大家介绍一款让你受益匪浅的神奇工具——网盘搜索引擎!它可以帮助你免费搜索查询各种云盘共享资源,包括影视作品、纪录片、小说、动漫等等。现在,我们急需网络流量&a…...

Mysql以key-val存储、正常存储的区别
场景 你作为一个服务端工程师,假设产品要求设计这么一个页面,页面上包含很多模块,每个模块都可以单独进行变更,有些模块是富文本。 实现方式有很多,我们来聊比较常用的两种,看看mysql的表如何设计。 第一…...

MySQL 索引优化实践(单表)
目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…...

react create-react-app v5配置 px2rem (暴露 eject方式)
环境信息: create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤: 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…...

AVL树的实现及原理
目录 AVL树的由来 AVL的实现原理 左单旋 右单旋 先左后右 先右后左 总结 AVL树的由来 查找,无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找,可是它的效率很低下,又演变出来了二分查找,它的效率非常…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...