【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树的由来 查找,无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找,可是它的效率很低下,又演变出来了二分查找,它的效率非常…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...