【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树的由来 查找,无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找,可是它的效率很低下,又演变出来了二分查找,它的效率非常…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
