字符串函数剖析(2)

news2024/11/20 10:29:21

最慢的步伐不是跬步,而是徘徊;最快的脚步不是冲刺,而是坚持。——《人民日报》

在这里插入图片描述

字符串函数的重点:

文章不长,是为了让你一点点消化所有内容:
在这里插入图片描述

1.strncpy函数的脾气

  • 1.1模拟实现strncpy函数

2.strncmp函数的脾气

  • 2.1模拟实现strncmp函数

3.strncat函数的巧解

  • 3.1模拟实现strncat函数

strncpy函数

先来看一下,strncpy函数的声明:

char * strncpy ( char * destination, const char * source, size_t num );

与strcpy函数相比,strncpy函数只是多了一个参数:size_t num,也就是需要复制的长度

来看一下下面的例子:
在这里插入图片描述
这里是将arr2中的字符串拷贝到arr1中,指定拷贝4个,arr2不是刚好有4个字符吗,为什么会出现这样的结果呢?
在这里插入图片描述
注意看右边,arr2末尾还有一个\0未拷贝过去
在这里插入图片描述
如图:
当我们将 拷贝长度4改成5时,就可以完成了
在这里插入图片描述
所以说,strncpy函数还是比较乖的,我们让他拷贝几个,他就拷贝几个,但是,看到这里,它是真的乖吗?
再看下面,假如我把长度5改成长度10呢

在这里插入图片描述
可以发现,strncpy函数不仅帮我们将第五个改成了\0,还将超出arr2本身的长度那一部分,都改成了\0,所以,这是乖还是懂事还是自作聪明,留给你进一步探讨。

再有一个问题:
我们刚开始是将arr2拷贝到arr1中,很明显,arr2的长度小于arr1的长度,但是当我们将arr1的长度拷贝到arr2中呢?

int main()
{
	char arr1[] = "hello world";
	char arr2[] = "qwer";
	strncpy(arr2, arr1, sizeof(arr1)); 
	//这里只是为了演示目标空间不够大,才写sizeof(arr1)
	printf("%s\n", arr1);
}

实践出真知:
在这里插入图片描述
在这里插入图片描述
翻译可得,意思就是,所拷贝的内容超出了arr2的数组的范围,造成数组越界了。
所以,strcpy的注意事项
有几点:
在这里插入图片描述

模拟实现strncpy

char* my_strncpy(char* arr1, const char* arr2, int sz)
{
	assert(arr1 && arr2);
	char* ret = arr1;

	while (sz &&(*arr1++ = *arr2++)!= '\0') 
	{
		sz--; 
	}
	if (sz) 
	{
		while (--sz) //注意,如果是sz--,会多更改一次'\0'
		{
			*arr1++ = '\0';
			//根据strncpy函数的分析,多余的长度全部要改写成\0
		}
	}
	return ret;
}

int main()
{
	char arr1[] = "hello world";
	char arr2[] = "qwer";
	char*ret = my_strncpy(arr1, arr2, 10);
	printf("%s\n", ret);
}

情况1:当arr1 = ‘\0’时,意味着arr2已经全部拷贝到arr1中
情况2:当sz=0时,已经完成拷贝
上面的代码是情况1,如果想出现情况2,只需将所需要拷贝的长度更改到小于源数组的长度
在这里插入图片描述
结果如上:
当我们设置成–sz时,会多更改一次’\0’,结果如下:,虽然打印出来不会改变,但是内部已经发生改变
在这里插入图片描述
arr1[10]已经被更改成了 ‘\0’

2.strncmp函数的详解

先来看一下strncmp函数的声明:

int strncmp(const char* str1, const char* str2, size_t num);

与strcmp函数相比,strncmp函数只是多了一个参数:size_t num,也就是所需要相比的字节的个数。

来到例题感受一下:

int main()
{
	char arr1[] = "abcd";
	char arr2[] = "abcdef";
	int ret =strncmp(arr1, arr2, 3);
	printf("%d\n", ret);
}

我们需要比较strncmp函数的前面三个字节,(由于一个字符大小是一个字节),即比较前三个字符的大小,很明显,arr1和arr2中的前三个字符的大小都相等在这里插入图片描述
由上图,当 arr1第一个字符 - arr2第一个字符时,若<0,则返回一个<0的数字,若>0,则返回一个>0的数字,若相等,则返回0;
在这里插入图片描述
所以结果一目了然。

当我们比较前5个字节时,很明显,arr1<arr2,所以返回一个<0的数字。
在这里插入图片描述

模拟实现strncmp函数

int my_strncmp(const char* str1, const char* str2, unsigned int num)
{
	assert(str1 && str2);
	while (num-- && *str1 && *str1 == *str2) 三种退出循环的情况
	{
	1.num退出循环后,俩字符串相等
	2.*str1=='\0'时,可能相等,可能不相等
	3.*str1 !=*str2,必不相等
	
		str1++; 
		str2++; 
	}
	return *str1 - *str2; 
	不管哪种情况,退出循环之后,*str1 - *str2都能满足要求
}

重要代码部分已加解释。
下面来看一下结果:
在这里插入图片描述
这里返回-101的原因是,比较第五个字符(即第五个字节)时,arr1中的第五个字符是’\0’,arr2中的第五个字符是e,'\0’对应的ascii码值是0,e对应的ascii码值是101, 0-101 = -101
在这里插入图片描述
不管值为多少,库中的strncmp返回-1,模拟的strncmp返回-101,都小于0,都能够比较两字符串的大小。但是在visual studio环境下,strncmp和strcmp函数对于小于0或者大于0的数字,统一返回-1和1
在这里插入图片描述
在这里插入图片描述
比较一下,证明了上述的结论。所以,在模拟实现该函数时,个人认为,具体到返回的值为两个字符之间的差,更易于理解。
因为由差可以得出具体到哪两个字符不相等,差值是多少。

注意事项 -
1.目标空间必须足够大,
2.目标空间必须可修改
3.源字符串必须以’\0’结束

3.strncat函数的巧解

char* strncat(char* destination, const char* source, size_t num);

与strcat函数相比,strncat函数仍然是多了一个参数:size_t,这个参数是说:追加的字节个数。
注意,函数的追加是在\0后面追加的

来看例题感受一下:

int main()
{
	char arr1[20] = "hello";
	char arr2[] = "world";
	strncat(arr1, arr2, 3);
}

在arr1的\0后面追加3个字节,这三个字节来源于arr2,追加结果就是 “hellowor” ,后面默认加上了\0。

那为什么会自己在\0后面追加呢?

看一下库函数的介绍,就是在 \0 后面追加字符
在这里插入图片描述
注意:(1)当num 小于 源字符串的长度时,库函数strncat会主动加上’\0’,假如这里 num = 3,追加的时候,从arr1中的后面的\0开始追加,追加三个,即hellowor
但是在r后面,strncat会主动加上一个,就一个\0,至于后面有没有追加到num个,strncat也不管了
(2)当num 大于 源字符串的长度时,库函数strncat ,假如num = 8 ,尽管num大于arr2的长度,strncat仍然在追加完成后,主动加一个\0,且仅加一个,后面的也不管了。


我们来验证一下:
在这里插入图片描述
(1)当num小于源字符串时,会主动在最后面加上一个\0,且只加一个。
在这里插入图片描述
(2)当num大于源字符串时,会主动在最后面加上一个\0,且只加一个。
总结:
不管num大于还是小于 源字符串的长度,strncat都会主动在最后面加上一个 \0, 注意:就加一个

了解了库中的strncat函数后,我们来模拟实现my_strncat 函数

3.1模拟实现my_strncat函数

char* my_strncat(char* dest, const char* src, unsigned int num)
{
	assert(dest && src);
	char* ret = dest;
	while (*dest++) //不使用++*dest是因为,假如dest是一个空字符串,进入循环之后,就已经跳过了'\0',造成越界访问,发生意外
	{
		;//找到目的地字符串的\0
	}
	dest--;//退出循环后,dest指向了'\0'的后一位,所以需要dest--
	while (num--)
	{
		if ((*dest++ = *src++) == 0)
		{
			return ret;//意味着源字符串遇到\0了,已经追加完成。但是num未到0
		}
	}
	*dest = '\0'; // 退出循环后,表明num的值不为正数了,此时dest指向了'\0'的后一个位置,将此位置置为'\0'
	return ret;
}

重点部分已有注释详细介绍,根据上面对库函数的strncat的分析,我们我们需要在最后面主动加上一个 \0 .
在这里插入图片描述
可以看到,结果与预期相符。
注意:
- 1.目标空间必须足够大,
2.目标空间必须可修改
3.源字符串必须以’\0’结束

一次性看到这里,你需要回去消化一下上面的内容,不然你会吃不消,剩下的重点,我们下期见!

看到这里,如果你觉得对你有帮助,不妨关注一下,持续为你输出更高质量的知识。在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

马化腾说视频号是全公司希望

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 这应该是&#xff0c;腾讯这家公司创办以来&#xff0c;马化腾最焦虑也最外露的一次讲话了&#xff0c;对于腾讯内部的大会&#xff0c;马化腾先生作了重要发言&#xff0c;因其在内部员工大会的讲…

边界网关协议BGP(计算机网络-网络层)

目录 因特网分层路由 分层路由和自治系统 边界网关协议 BGP BGP 的设计目标 BGP 发言人 路径向量算法 BGP 协议的要点 因特网分层路由 规模问题 路由选择算法将很难收敛 交换的路由信息会占用大量的带宽 管理问题 许多单位不愿意外界了解自己单位网络的具体细节 希望采用…

新能源汽车补贴即将取消,汽车金融的促进作用逐渐显现

中国新能源汽车产业发展强劲。自2015年起&#xff0c;新能源汽车销量连续7年位居世界第一。特别是2021年以来&#xff0c;在政策支持、技术驱动、消费者接受度提升等多重因素共同影响下&#xff0c;中国新能源汽车市场实现了超越式的发展。2022年1-10月&#xff0c;新能源汽车批…

这份京东T8级程序员整理的新版Spring Cloud手抄本,把微服务讲透了

近几年&#xff0c;微服务可谓是红的发紫&#xff0c;仿佛一时间所有系统无不以拆分为荣&#xff0c;以构建烟囱型应用为耻。最近&#xff0c;一位朋友刚好赶上公司基础服务的微服务化项目&#xff0c;加上之前又主动学习了不少微服务的内容&#xff0c;便主动请缨参与到项目里…

前端实现网站悼念【灰色效果】几行代码轻松解决

博主介绍 &#x1f4e2;点击下列内容可跳转对应的界面&#xff0c;查看更多精彩内容&#xff01; &#x1f34e;主页&#xff1a;水香木鱼 &#x1f34d;专栏&#xff1a;CSS3 文章目录 简介&#xff1a;这是一篇有关【前端实现网站悼念【灰色效果】几行代码轻松搞定】的文章&…

遗传编程(Genetic Programming, GP)

1. 绪言 1.1 遗传编程概述 \quad\quad自计算机出现以来&#xff0c;计算机科学的一个重要目标是让计算机自动进行程序设计&#xff0c;即只要明确地告诉计算机要解决的问题&#xff0c;而不需要告诉它如何去做&#xff0c;遗传规划便是在该领域内的一种尝试。它采用遗传算法的…

IDEA反编译Jar包

一.安装Java Bytecode Decomplier插件 (1) File–>Settings–>Plugins &#xff0c;搜索 Java Bytecode Decomplier 插件 (2) 查看安装插件的路径 File->Import Setting 注意&#xff1a;如果你的插件里面搜不到 Java Bytecode Decomplier&#xff0c;但是能搜到…

spring之Bean的生命周期

文章目录一、Bean的生命周期之五步1、准备User类2、spring配置文件3、测试类4、运行结果二、Bean的生命周期之七步1、实现BeanPostProcessor类2、配置文件3、运行结果&#xff1a;三、Bean的生命周期之十步1、点位12、点位23、点位3四、Bean的作用域一、Bean的生命周期之五步 …

Coinbase或在不久使用Zebec发放工资,并对Web3支付赛道发展寄予厚望

流支付协议Zebec Protocol目前已经完成了生态向BNB Chian上的迁移&#xff0c;目前得到了以PancakeSwap为代表的头部生态的支持。在12月20日Zebec生态在PancakeSwap官方的支持下&#xff0c;经过社区投票&#xff0c;ZBC通证上线了糖浆池&#xff0c;并有望继续上线Binance。而…

ELK集群部署---Kibana的部署

1. 环境规划&#xff1a; 主机名IP地址角色node1192.168.56.111 ElasticSearch(master) Zookeeper Kafka node2192.168.56.112 ElasticSearch(slave) Kibana Zookeeper Kafka node3192.168.56.113 ElasticSearch(slave) Zookeeper Kafka node4192.168.56.114 Logstash Filebe…

优雅数据同步--canal实现mysql同步demo

当需要两张表数据同步的时候&#xff0c;我们会想到几种方案&#xff1f; 最简单的一种方式就是触发器的方式。例如A同步到B,可以通过下面的sql来添加触发器 create trigger tri_trade_update after UPDATE on A for each row begin update B set company_id new.compan…

数据结构和算法学习——稀疏数组

目录 一、数据结构和算法的关系 二、数据结构的分类 (一)线性结构 (二)非线性结构 三、稀疏数组(sparsearray) (一)稀疏数组的基本介绍 (二)稀疏数组的处理方法 一、数据结构和算法的关系 数据data结构(structure)是一门研究组织数据方式的学科&#xff0c;有了编程语言…

Grafana 查询数据和转换数据

Grafana 系列文章&#xff0c;版本&#xff1a;OOS v9.3.1 Grafana 的介绍和安装Grafana监控大屏配置参数介绍&#xff08;一&#xff09;Grafana监控大屏配置参数介绍&#xff08;二&#xff09;Grafana监控大屏可视化图表Grafana 查询数据和转换数据 介绍 Grafana能够支持各…

微服务网关GateWay

在微服务架构下&#xff0c;网关的本质&#xff0c;其实就是对请求进行路由转发&#xff0c;在此基础上我们可以根据网关在整个微服务架构中的特殊位置&#xff0c;对请求进行前置和后置的处理。 请求转发和路由&#xff1a;网关类似于一个门面&#xff0c;微服务的组织细节对…

三维数字化开发管理中心

目录一、前言二、项目依赖2.1 后端2.2 前端三、快速运行3.1 启动后台服务3.2 启动前台页面四、使用手册4.1 登录4.2 首页4.3 资源中心4.4 在线预览4.5 三维开发4.6 信息管理4.6.1 用户信息4.6.2 模型信息4.7 个人中心五、数据库5.1 数据需求5.2 数据流图5.3 数据字典1&#xff…

马斯克辞任CEO,产品经理如何用项目协作软件武装自己?

自马斯克接管推特以来&#xff0c;已经发起了多轮裁员潮&#xff0c;仅第一波就裁掉了50%的员工。11月14日&#xff0c;马斯克开启第二波裁员。而IT之家12 月 21 日消息&#xff0c;埃隆・马斯克在推特发文对网友的投票结果做出回应&#xff0c;称会尽快找到一个足够傻的人来接…

蓝桥杯备赛Day3——基础数据结构(一维数组)

目录 数据结构 什么是数据结构? 《数据结构》教材一般包含 基础数据结构 最简单的数据结构——一维数组 一维数组的定义 一维变长数组 一维正向遍历 一维反向遍历 一维数组区间操作&#xff08;实际上就是切片操作&#xff09; 一维数组从a[1]开始赋值 一维数组的读…

热门项目披露:四川超声印制板有限公司100%股权转让

热门项目披露&#xff1a;四川超声印制板有限公司100%股权转让 项目推荐指数&#xff1a;&#xff1b;该项目由 北京产权交易所 发布&#xff0c;于2022年12月11日被塔米狗平台收录。 项目方 四川超声印制板有限公司&#xff0c; 成立于 1998年7月5日 &#xff0c; 注册资金 2…

Unity 3D Hierarchy 视图 || Unity 3D Project 视图

Unity 3D 的 Hierarchy 视图包含了每一个当前场景的所有游戏对象&#xff08; GameObject &#xff09;&#xff0c;如下图所示。 其中一些是资源文件的实例&#xff0c;如 3D 模型和其他预制物体&#xff08; Prefab &#xff09;的实例&#xff0c;可以在 Hierarchy 视图中选…

Mac 截图工具 iShot Pro - 软件介绍、下载安装详细教程

Mac 截图工具 iShot Pro -软件介绍、下载安装详细教程 iShot -优秀&#xff0c;功能齐全的区域截图&#xff0c;窗口截图&#xff0c;多窗口截图&#xff0c;长屏幕截图&#xff0c;shell截图&#xff0c;时间间隔截图&#xff0c;快速注释&#xff0c;纹理&#xff0c;颜色匹配…