模拟实现字符串函数(长度受限制的详讲)
上次发布了长度不受限制的字符串函数的模拟实现方法,这次就给大家说说长度受限制的字符串函数。首先,长度受限制和不受限制有什么区别呢?其实从某种意义上来讲,长度受限制的字符串函数比长度不受限制的字符串安全,为什么安全呢?下面就让我们看看长度受限制的字符串函数到底在哪安全了,安全到哪了,
1.strncpy

首先来看这个函数的前两个参数都不用说(如果有不懂的小伙伴可以看我上一篇博客),第三个参数的意思是拷贝几个字符,返回类型就不用说了吧,直接看库里面函数的代码以及调试过程以及打印:
//int main()
//{
// char arr[] = "abcdef";
// char arr1[20] = "xxxxxxxxxxxxxx";
// char* p = strncpy(arr1, arr, 12);
// printf("%s", p);
// return 0;
//}


其实仔细观察,你会发现我们要拷贝的字符个数大于了要拷贝字符串的长度,那么,大家想想,会发生什么,我们看到调试的时候已经拷贝完成,但是拷贝完成之后,多余的那些字符怎么办呢?其实,再用strncpy时,多余的字符会用‘\0’来代替。
那么我们看一下我们自己模拟实现的这个函数到底与库函数的功能项不相同呢?看下面:
char* my_strncpy(char* dest, const char* src, size_t num)
{assert(dest && src);char* tem = dest;while (num){if (*src != '\0'){*dest++ = *src++;num--;}else{*dest++ = '\0';num--;}}return tem;
}
int main()
{char arr[] = "abcdef";char arr1[20] = "xxxxxxxxxxxxxxxxx";char* p = my_strncpy(arr1, arr, 12);printf("%s", p);return 0;
}



我们可以看到的是我们模拟实现的这个函数功能与库里的函数功能相同,调试过程也是相同的,多余字符用了‘\0’来代替。这个函数的注意事项和strcpy的一样,就不在这里多说了,而我想说说他与strcpy的区别是:首先,strcpy是拷贝整个字符串,不受长度限制,只要使用,就是整个字符串拷贝,而strncpy是受字符串长度限制的,他一般是会看第三个参数是几就拷贝几个字符过去,所以这个要注意,如果要是拷贝的字符个数小于源头字符串的长度的话,拷贝完之后是不加‘\0’的,举个例子:
char* my_strncpy(char* dest, const char* src, size_t num)
{assert(dest && src);char* tem = dest;while (num){if (*src != '\0'){*dest++ = *src++;num--;}else{*dest++ = '\0';num--;}}return tem;
}
int main()
{char arr[] = "abcdef";char arr1[20] = "xxxxxxxxxxxxxxxxx";char* p = my_strncpy(arr1, arr, 3);printf("%s", p);return 0;
}
就用我们自己实现的这个函数来写举例子吧,如果拷贝的字符数是3个,那么此时的arr1打印出来是这个结果

充分说明了在拷贝的时候没有加‘\0’,说几个就是几个。
2.strncat

这个函数的返回类型,形参与上面相同,就不在多说,他的功能是追加字符串,先上代码理解一下这个函数。
int main()
{char arr[100] = "hello xxxxxxxxxx";char arr1[] = "world";strncat(arr, arr1, 4);printf("%s", arr);return 0;
}


要注意的是这个函数在追加完限制的长度后,会自动加上\0,这个是与strcat不同的,下面我们来自己实现一下这个函数,
char* my_strcat(char* dest, const char* src, size_t num)
{assert(dest && src);char* tem = dest;while (*dest++);dest--;while (num){if (*src){*dest++ = *src++;num--;}else{break;}}*dest = '\0';return tem;
}
int main()
{char arr[20] = "hello \0xxxxxxx";char arr1[] = "world";char* p = my_strcat(arr, arr1, 4);printf("%s", p);return 0;
}


这个结果与我们想要的看到的结果正是一样的,如果要追加长度大于我们圆头的字符串,那么就把整个源头字符串追加上去就好,多余的不会像strncpy一样补'\0',感兴趣的可以自己测试一下,这个函数的注意事项与strcat也是基本一样,这里就不再多说。
3.strncmp

这个函数与strcmp的参数与返回类型一样,这里不再多说,这个函数的功能就是对比字符串的大小,具体规则是什么呢?我们来仔细看看库里的
int main()
{char arr[20] = "abcd";int t = strncmp(arr, "hjk", 100);printf("%d", t);return 0;
}
这个函数其实个人感觉也看不出什么,因为这个没有改变两个字符串的内容,所以就不在调试,直接看结果吧,

对比结果很简单,这个不用我说,一眼就可以看出来,直接看看我们的模拟实现代码吧
int my_strncmp(const char* str, const char* str1,size_t num)
{assert(str && str1);while (num){if (*str == *str1){str++;str1++;num--;}else{return *str - *str1;}}return 0;
}
int main()
{char arr[] = "hfjklsadhfjksdhajkf";char arr1[20] = "hfjklsadhfjksdhajk";int ret = my_strncmp(arr, arr1,19);printf("%d", ret);return 0;
}
这个实现过程思路和strcmp其实非常类似,唯一不同的就是,strcmp循环出来以后要判断,而strncmp这个函数出来以后就不需要判断,他们的循环条件不一样。我们来看看打印结果

用库里的函数打印的结果是1,而我用的返回结果是*str-*str1,所以就返回的是102,还是根据个人喜好来写,返回1没有错,但是库里函数明显显示的是返回大于0小于0等于0的数,所以只要符合这个规则就可以。
总结:长度受限制和不受限制的字符串函数其实注意事项是差不多的,都是一一对应的,那么,我们现在来说一下为什么受限制的比不受限制的函数相对来说是安全的呢?打个比方,就以strcpy和strncpy来做比较,在使用时,如果我们不小心拷贝的时候,目的地的空间大小不够了,那么此时他还是会拷贝,但是打印的时候才会出现栈被破坏的通知(这个是strcpy),而strncpy这个函数就比较安全了,因为他受长度的限制,所以每次打印的时候,(如果不是故意的话)不会出现站被破坏的情况。其他的几个函数其实和这个是一样的道理,慢慢想就可以理解,这里不再多说。
最后,如果大家感觉又用的话,就点一下赞吧!支持一下!谢谢!
相关文章:
模拟实现字符串函数(长度受限制的详讲)
上次发布了长度不受限制的字符串函数的模拟实现方法,这次就给大家说说长度受限制的字符串函数。首先,长度受限制和不受限制有什么区别呢?其实从某种意义上来讲,长度受限制的字符串函数比长度不受限制的字符串安全,为什…...
分布式ID生成方案总结
什么是分布式 ID 分布式 ID 是指,在分布式环境下可用于对数据进行标识且易存储的全局唯一的 ID 标识。 为什么需要分布式 ID 对于单体系统来说,主键ID可能会常用主键自动的方式进行设置,这种ID生成方法在单体项目是可行的。 对于分布式系统…...
极智AI | 百度推出文心一言,对标ChatGPT功力几成
欢迎关注我,获取我的更多经验分享,极智传送《极智AI | 百度推出文心一言,对标 ChatGPT 功力几成》 大家好,我是极智视界,本文介绍一下 百度今日推出文心一言,对标ChatGPT功力几成。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https…...
CleanMyMac X最新版本4.12.6
系统要求macOS 10.12及更高,M1机型及最新macOS 13 CleanMyMac可以为Mac腾出空间,软件已经更新到CleanMyMac X支持最新版Mac系统。CleanMyMac具有一系列巧妙的新功能,可让您安全,智能地扫描和清理整个系统,删除大量未使…...
替代notepad++,notepad--介绍及插件cmake编译
Notepad 是一个文本编辑器小软件,用来替代windows自带的记事本。然而Notepad软件的作者是台湾省人,其具有明显的gd/jd/td倾向,如果你不赞同他的观点,Notepad将会在你的源码里面插入随机字符。推荐一款国产的开源跨平台软件NDD(not…...
机器学习笔记之集成学习(四)Gradient Boosting
机器学习笔记之集成学习——Gradient Boosting引言回顾:Boosting\text{Boosting}Boosting算法思想与AdaBoost\text{AdaBoost}AdaBoostGradient Boosting\text{Gradient Boosting}Gradient Boosting算法介绍场景构建算法过程迭代过程与梯度下降法之间的关联关系引言 …...
WPA渗透-pyrit:batch-table加速attack_db模块加速_“attack_db”模块加速
WPA渗透-pyrit:batch-table加速attack_db模块加速_“attack_db”模块加速 1.渗透WIFI 1.导入密码字典 pyrit -i 字典文件 import_passwords -i:输入的文件名 import_passwords:从类文件源导入密码。pyrit -i pwd.txt import_passwords2.导…...
kotlin第二部分复习纪要
扩展函数。 例如: fun Context.toast(msg: String, length: Int Toast.LENGTH_SHORT){Toast.makeText(this, msg, length).show() } 使用 val activity: Context? getActivity() activity?.toast("Hello world!") activity?.toast("Hello worl…...
代码随想录--链表--删除链表第n个节点题型、链表相交题型
删除链表第n个节点题型 链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点 (opens new window) 这道题我一开始想的是,倒数第n个节点,链表不方便往前找,那就从链表头结点开始找链表长度减n,这时候就是…...
一起来学5G终端射频标准(In-band emissions-2)
上一篇我们列出了IBE的测试要求表格,今天我们详细说一下IBE如何测量计算,以及CA/NR-DC/SUL/UL-MIMO/V2X/Tx Diversity模式下的IBE情况。01—IBE如何测量和计算IBE的测试是对落入到未被分配的RB的干扰的测量,为12个子载波的平均发射功率&#…...
硬刚ChatGPT,中国版ChatGPT“狂飙”的机会在哪儿?
整体来讲,个人的态度是积极的。 ChatGPT、文心一言 都是在多重因素及大量 AI 模型/数据 长时间累积的成果,不是一蹴而就,立竿见影的功能产品。两者产生的基础和背景均不相同,各有优劣,不存在强行对比的概念。 以下是 …...
ReactNative——导航器createBottomTabNavigator(底部标签导航器篇)
上一篇有讲到堆栈式导航器的写法,点这里->堆栈式导航器标签导航器官网链接先安装依赖包yarn add react-navigation/bottom-tabs接着在src/navigator文件夹下新建BottomTabs.tsx文件,写法跟堆栈式导航器类似的~import React from react; import { NavigationConta…...
【数据结构】带头双向循环链表的实现
🌇个人主页:平凡的小苏 📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情 🛸C语言专栏:https://blog.csdn.net/vhhhbb/category_12174730.html 🚀数据结构专栏ÿ…...
软件开发的权限系统功能模块设计,分享主流的九种常见权限模型
软件系统的权限控制几乎是非常常见且必备的,这篇文章整理下常见的九种模型,几乎基本够你用了,主流的权限模型主要有以下9种: 1、ACL模型 访问控制列表 2、DAC模型 自主访问控制 3、MAC模型 强制访问控制 4、ABAC模型 基于属性的访…...
CSS3-数据可视化
2D动画 - transform CSS3 transform属性允许你旋转,缩放,倾斜或平移给定元素。 Transform是形变的意思(通常也叫变换),transformer就是变形金刚 常见的函数transform function有: 平移:transl…...
硬件系统工程师宝典(15)-----PCB上的EMC设计,“拿捏了”
各位同学大家好,欢迎继续做客电子工程学习圈,今天我们继续来讲这本书,硬件系统工程师宝典。上篇我们说到PCB常用的多层板叠层结构,综合成本、性能、需求考虑选择不同的叠层结构。今天我们来看看为提高EMC性能,在PCB设计…...
vue3滚动条滚动后元素固定
代码地址:https://gitee.com/zzhua195/easyblog-web-vuee Framework.vue 在这个布局组件中,监听main的滚动事件,获取滚动的距离,将它存入store,以便其它组件能够共享,监听到 <template><div c…...
新吲哚菁绿染料IR-825 NHS,IR825 NHS ester,IR825 SE,IR-825 活性酯,用于科研实验研究和临床
IR825 NHS理论分析:中文名:新吲哚菁绿-琥珀酰亚胺酯,IR-825 琥珀酰亚胺酯,IR-825 活性酯英文名:IR825 NHS,IR-825 NHS,IR825 NHS ester,IR825 SECAS号:N/AIR825 NHS产品详…...
GO语言--接口(interface)的定义及使用
接口定义 接口也是一种数据类型,它代表一组方法的集合。 接口是非侵入式的。即接口设计者无需知道接口被哪些类型实现,而接口使用者只需知道实现怎样的接口,并且无须指明实现哪一个接口。编译器在编译时就会知道哪个类型实现哪个接口&#…...
【Python语言基础】——Python MongoDB 查询
Python语言基础——Python MongoDB 查询 文章目录 Python语言基础——Python MongoDB 查询一、Python MongoDB 查询一、Python MongoDB 查询 筛选结果 在集合中查找文档时,您能够使用 query 对象过滤结果。 find() 方法的第一个参数是 query 对象,用于限定搜索。 实例 查找地…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
