【C语言】长篇详解,字符系列篇2-----strcat,strcmp,strncpy,strncat,strncmp函数的使用和模拟实现【图文详解】

欢迎来CILMY23的博客喔,本期系列为【C语言】长篇详解,字符系列篇2-----“混杂”的字符串函数,字符串函数的使用和模拟实现【图文详解】,图文讲解各种字符串函数,带大家更深刻理解C语言中各种字符串函数的应用,感谢观看,支持的可以给个赞哇。

前言

上一篇说到,在C语言中,我们常常碰见各种字符,也需要对字符进行处理,那C语言提供了一系列的库函数,来帮助我们处理各种情况。字符函数有字符串函数,字符分类函数,还有字符转换函数……本期我们将深入了解各种字符串函数(strcpy,strcat,strcmp,strncpy,strncat)

目录

 一、strcat函数

二、strcmp函数

三、strncpy函数

四、strncat函数

五、strncmp函数


一、strcat函数

 该函数可以在cplusplus网站查询到,strcat - C++ Reference (cplusplus.com)

 函数原型如下:

char * strcat ( char * destination, const char * source );

函数介绍如下: 

 返回值和使用案例:

 

先简单了解一下strcat函数吧,strcat函数它的功能是Concatenate strings,意思是连接字符串。concatenate它的意思如下

了解完这个功能后,我们大致也清楚了,strcat的作用就是拼接字符串啦,那函数的使用如下:

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[50] = "hello ";
	char str2[] = "CILMY23";
	
	strcat(str1, str2);
	printf("%s ", str1);

	return 0;
}

我们可以把第二个字符串拼接到第一个字符串末尾,这样就concatenate起来了。 

结果如下:

总结:

1.strcat的功能是拼接字符串,目标空间要有'\0',并且源字符串要有'\0'。

2.strcat的使用需要包括头文件string.h

3.strcat的返回地址是destnation的地址

4.目标空间要足够大,并且可以修改

   strcat的模拟实现 

我们看以下这段最简单粗暴的代码,思路是比较直接的,先遍历所需要追加的字符串空间,找到'\0'的位置,然后从'\0'的位置开始用新的字符串覆盖,最后添加'\0'就行。 

char* my_strcat(char * dest, const char* src)
{
	assert(dest);
	assert(src);

	char* ret = dest;

	while (*dest != '\0')
	{
		dest++;
	}

	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';

	return ret;
}

 逻辑图如下所示:

代码还可以进行优化,那如何优化呢?实际上我们可以发现,后面一段有点类似于把str2给它复制到str1当中,这不就是我们字符篇1学到的strcpy嘛,(不懂可以跳转连接http://t.csdnimg.cn/CvvpI) 

所以第二步的优化就可以写成这样

char* my_strcat(char * dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;

	while (*dest != '\0')
	{
		dest++;
	}

	strcpy(dest, src);

	return ret;
}0

二、strcmp函数

该函数可以在cplusplus查找到:strcmp - C++ Reference (cplusplus.com)

函数原型如下:

int strcmp ( const char * str1, const char * str2 );

 函数介绍如下:

函数返回值和使用案例:

简单了解一下strcmp函数吧,它的功能是Compare two strings,Compares the C string str1 to the C string str2.,比较两个字符串,它的返回值是如果是第一个字符串小于第二个字符串就返回一个小于0的值,如果第一个字符串和第二个字符串相等就返回0,如果第一个字符串大于第二个字符串,就返回一个大于0的值。

strcmp的使用:

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[] = "hello ";
	char str2[] = "CILMY23";
	
	int ret = strcmp(str1, str2);
	printf("%d ", ret);

	return 0;
}

 解析:因为h是在ASCII码比C大的,所以返回了1

 总结:

1.strcmp实际是按照两个字符串对应位置一个个进行比较的,而且是按照字典序(ASCII码值)比较的

2.strcmp的使用需要包括头文件string.h

3.返回值:

◦    第⼀个字符串大于第二个字符串,则返回大于0的数字
◦    第⼀个字符串等于第二个字符串,则返回0
◦    第⼀个字符串小于第二个字符串,则返回小于0的数字

strcmp的模拟实现

字符串相对比的三种情况,相等,大于,和小于,如果字符串两个相对比是相等的话,那指针就需要往后走,它们结束的标志是‘\0’,如果走到了这个‘\0’,那说明两个字符串是相等的,出了循环后,那说明二者不相等,就进行判断,根据判断后写返回值。

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);

	while (*str1 == *str2)
	{
		if (*str1  == '\0')
			return 0;
		str1++;
		str2++;
	}

	if (*str1 > *str2)
		return 1;
	else
		return -1;
}

 当然后面的返回值也可以用指针解引用后相减得到的值,不固定,主要是灵活使用,

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);

	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}

	return *str1 - *str2;
}

这是当str1和str2相等的情况下:注意图片中红色的是字符数组,而黑色的str1和str2是指针。 

当二者不相等的时候: 

 

就会马上比对出结果。

我写的几个测试用例也给大家放这了:

int main()
{
	char str1[] = "CILMY23";
	char str2[] = "CILMY23";
	char str3[] = "";
	char str4[] = "helllo ";

	int ret = my_strcmp(str1, str2);
	printf("%d \n", ret);
	ret = my_strcmp(str3, str2);
	printf("%d \n", ret);
	ret = my_strcmp(str4, str2);
	printf("%d \n", ret);
	ret = my_strcmp(str3, str4);
	printf("%d \n", ret);

	return 0;
}

三、strncpy函数

如果讲完以上三个函数相信大家对其都有个大致的了解了,那以上三个(strcpy,strcat,strcmp)都是长度不受限制的字符串函数,它们只会一股脑的走到尾巴,我想要只复制几个字符,链接几个字符,比较几个字符,这时候库函数就给我们提供了三个加n的字符串函数,它们分别是strncpy,strncat,strncmp函数,有了这三个函数,我们就可以指定几个字符来进行相对应的操作。 它们都在相对于的原型基础上,增加了一个形参size_t num。

首先我们先来认识一下strncpy这个函数,strncpy - C++ Reference (cplusplus.com)

函数原型如下:

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

函数介绍如下: 

  函数返回值和使用案例如下:

 函数的使用呢,重点还是如果字符串不够怎么办?

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[] = "CILMY23";
	char str2[50];

	strncpy(str2, str1, 9);

	printf("%s ", str2);

	return 0;
}

 我们知道九个复制是远超过str1的数量的,那内存里复制了什么过去呢?

通过下图我们可以看到在23后面放的是'\0',所以如果num超过源字符串之后,就会不停的拷贝'\0',直到复制结束。

总结:

•    拷贝num个字符从源字符串到目标空间。
•    如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。 

strncpy的模拟实现

char* my_strncpy(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);

	while (*dest++ = *src++)
	{
		if (num == 1)
		{
			*dest = '\0';
			break;
		}
		num--;
	}

	while (num > 1)
	{
		*dest++ = '\0';
		num--;
	}
	
	return ret;
}

 上述代码是我第一种思路,根据原先代码改造的,其实跟原来差不多,只是这里多了个num操作,因为我的循环它会先赋值,后判断,所以在我已经把C赋值给str2空间的时候,num还是3,I赋值给完str2的时候,num--后才是2,我L又复制完了,num--后1了,这个时候我已经操作三次赋值了,但是num并不为0,所以此刻等于1的时候要将0赋值进去,然后跳出循环再进行赋值‘\0’操作。

我的第二种思路就是通过判断num,num如果为0就结束了。因为源字符串的结束标志是'\0',那不是'\0',那我就是在复制'\0'之前的字符。那我就先赋值,把src的内容复制进去,因为复制进去后,dest和src都指向下一个位置了,这时候我把*dest直接用‘\0’覆盖,如果num--后为0,这个时候我就刚好只拷贝一个字符,那如果num是大于源字符串函数的,那么在复制完源字符串后,*src就停留在‘\0’ 了,这时候只要不断给dest添加'\0'就完事了。

char* my_strncpy(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);

	while (num--)
	{
		if (*src != '\0')
		{
			*dest++ = *src++;
		}
		*dest = '\0';
	}

	return ret;
}

测试部分:这里我是把原先的Cplusplus网站中的案例扣过来用了结果是一样的

int main()
{
	char str1[] = "To be or not to be";
	char str2[40];
	char str3[40];

	/* copy to sized buffer (overflow safe): */
	my_strncpy(str2, str1, sizeof(str2));

	/* partial copy (only 5 chars): */
	my_strncpy(str3, str2, 5);
	str3[5] = '\0';   /* null character manually added */

	puts(str1);
	puts(str2);
	puts(str3);

	return 0;
}

 我的逻辑可能会比较复杂,如果你有其他的方法欢迎在评论区探讨。

四、strncat函数

函数原型如下:strncat - C++ Reference (cplusplus.com)

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

函数介绍如下:

 函数返回值和使用案例如下:

 strncat的模拟实现

首先我仍然按照之前strncpy的第二种思路进行实现,我们需要先找到需要拼接的dest的尾巴'\0',然后从'\0'开始拼接。拼接的数量还是由num来决定。

char* my_strncat(char* dest, const char* src, size_t num)
{
	char* ret = dest;
	assert(dest && src);
	//找尾
	while (*dest != '\0')
	{
		dest++;
	}

	while (num--)
	{
		if (*src != '\0')
		{
			*dest++ = *src++;
		}

		*dest = '\0';
	}

	return ret;
}

 测试用例以及结果如下:

int main()
{
	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	
	my_strncat(str1, str2, 6);
	puts(str1);
	return 0;
}

 五、strncmp函数

 strncmp:strncmp - C++ Reference (cplusplus.com)

函数原型如下:

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

函数介绍如下:

函数返回值和使用案例如下: 

 strncmp的模拟实现

int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	while (num--)
	{
		if(*str1 == *str2)
		{
			if (*str1 == '\0')
				return 0;
			str1++;
			str2++;
		}
		else
		return *str1 - *str2;
	}
}

该思路来自之前写过的,我们只需要将不等于的返回即可 

感谢各位同伴的支持,本期字符函数篇2就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springmvc+ssm+springboot房屋中介服务平台的设计与实现 i174z

本论文拟采用计算机技术设计并开发的房屋中介服务平台&#xff0c;主要是为用户提供服务。使得用户可以在系统上查看房屋出租、房屋出售、房屋求购、房屋求租&#xff0c;管理员对信息进行统一管理&#xff0c;与此同时可以筛选出符合的信息&#xff0c;给笔者提供更符合实际的…

《Linux C编程实战》笔记:消息队列

消息队列是一个存放在内核中的消息链表&#xff0c;每个消息队列由消息队列标识符标识。与管道不同的是消息队列存放在内核中&#xff0c;只有在内核重启&#xff08;即操作系统重启&#xff09;或显示地删除一个消息队列时&#xff0c;该消息队列才会被真正的删除。 操作消息…

英伟达推出免训练,可生成连贯图片的文生图模型

目前&#xff0c;多数文生图模型皆使用的是随机采样模式&#xff0c;使得每次生成的图像效果皆不同&#xff0c;在生成连贯的图像方面非常差。 例如&#xff0c;想通过AI生成一套图像连环画&#xff0c;即便使用同类的提示词也很难实现。虽然DALLE 3和Midjourney可以对图像实现…

如何修改unity的背景颜色

要在Unity中将背景颜色设为黑色&#xff0c;可以按照以下步骤进行&#xff1a; 1、在Unity编辑器中&#xff0c;选择你想要修改背景颜色的摄像机对象&#xff08;一般是Main Camera&#xff09;。 2、在Inspector面板中&#xff0c;找到"Clear Flags"&#xff08;清…

掌握Redis核心:常用数据类型的高效运用秘籍!

在数据驱动的时代&#xff0c;高效地存储和处理数据成为了开发者们的重要任务。Redis&#xff0c;作为一个开源的高性能键值对&#xff08;key-value&#xff09;数据库&#xff0c;以其独特的数据结构和丰富的功能&#xff0c;成为了众多项目的首选。 今天&#xff0c;我们就…

高精度双向计量旋翼干式脉冲水表

在现代社会&#xff0c;水资源的合理利用与精确管理至关重要。随着科技的不断进步&#xff0c;水表技术也在迭代升级。今天&#xff0c;我们将探讨一种高科技水表——高精度双向计量旋翼干式脉冲水表&#xff0c;它如何改变我们的用水习惯&#xff0c;提升水资源管理的效率。 1…

Stable Diffusion 模型分享:FenrisXL(芬里斯XL)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 FenrisXL 是一个拟人化的 SDXL 模型&#xff0c;可以为动物们穿上人类的衣服&…

吴恩达机器学习全课程笔记第三篇

目录 前言 P42-P48 神经元和大脑 神经网络中的层 更复杂的神经网络 前向传播&#xff08;做出预测&#xff09; P49-P53 代码中的推理 构建一个神经网络 P54-P60 矩阵乘法 TensorFlow框架实现神经网络 前言 这是吴恩达机器学习笔记的第三篇&#xff0c;第二篇笔记…

苍穹外卖学习-----2024/02/21

1.新增员工 /*** 处理SQL异常* param sqlIntegrityConstraintViolationException* return*/ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException sqlIntegrityConstraintViolationException){//String message sqlIntegrityConstraintV…

IDEA启动Springboot报错:无效的目标发行版:17 的解决办法

无效的目标发行版&#xff1a;17 的解决办法 一般有两个原因&#xff0c;一可能是本地没有安装JDK17&#xff0c;需要安装后然后在IDEA中选择对应版本&#xff1b;二可能是因为IDEA版本太低&#xff0c;不支持17&#xff0c;需要升级IDEA版本。然后在File->Project Struct…

Zabbix 6.2.1 安装

目录 1、监控介绍 监控的重要性 网站的可用性 监控范畴 如何监控 2、Zabbix 介绍 zabbix 简介 zabbix 主要功能 zabbix 监控范畴 Zabbix 监控组件 zabbix 常见进程 zabbix agentd 工作模式 zabbix 环境监控中概念 3、搭建LNMP 拓扑规划 安装MySQL 安装 Nginx …

libpng编译-android端(libpng官网下载是没有android编译脚本)

libpng编译-android端&#xff08;libpng官网下载是没有android编译脚本&#xff09; 环境配置&#xff08;mac的原理一样可以自己配置&#xff0c;我在linux编译&#xff09; 配置ubuntu的ndk环境 1、执行 sudo vim /etc/profile&#xff0c;对Path的路径文件进行更改&…

python(23)——while循环

前言 在Python中&#xff0c;while 循环用于重复执行一段代码块&#xff0c;只要指定的条件保持为真&#xff08;True&#xff09;。一旦条件变为假&#xff08;False&#xff09;&#xff0c;循环就会终止。while 循环通常用于在不知道循环将执行多少次的情况下进行迭代。 w…

linux下开发,stm32和arduino,我该何去何从?

linux下开发&#xff0c;stm32和arduino&#xff0c;我该何去何从&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm3的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共…

React 模态框的设计(一)拖动组件的设计

春节终结束了&#xff0c;忙得我头疼。终于有时间弄自己的东西了。今天来写一个关于拖动的实例讲解。先看效果&#xff1a; 这是一个简单的组件设计&#xff0c;如果用原生的js设计就很简单&#xff0c;但在React中有些事件必须要多考虑一些。这是一个系列的文章&#xff0c;…

Megalinter 初体验

简介 MegaLinter 是一个多语言、多工具的集成代码检查工具&#xff0c;它能够通过一个统一的工作流来运行多个静态代码分析工具&#xff0c;从而提供全面的代码质量检查。 官网&#xff1a;https://megalinter.io/latest/ MegaLinter 的特点&#xff1a; 多语言支持&#x…

深入理解指针(c语言)

目录 一、使用指针访问数组二、数组名的理解1、数组首元素的地址2、整个数组 三、一维数组传参的本质四、冒泡排序五、二级指针六、指针数组 一、使用指针访问数组 可以使用指针来访问数组元素。例如&#xff0c;可以声明一个指针变量并将其指向数组的第一个元素&#xff0c;然…

QT-模拟电梯上下楼

QT-模拟电梯上下楼 一、演示效果二、核心程序三、下载链接 一、演示效果 二、核心程序 #include "ElevatorController.h" #include <QGridLayout> #include <QLabel> #include <QGroupBox> #include <QGridLayout> #include <QPushButto…

2024「诺奖风向标」斯隆奖出炉:杨笛一、杜少雷、清华校友姜楠、北大校友金驰等入选​

今天&#xff0c;斯隆基金会公布了 2024年度斯隆研究奖&#xff08;Sloan Research Fellowship&#xff09;获得者名单&#xff0c;本次斯隆研究奖共颁发给了126 人&#xff0c;其中计算机科学领域 共有 7名华人学者当选。 包括斯坦福大学杨笛一&#xff08;上海交大ACM班校友…

2.5《Python3 网络爬虫开发实战》学习之实例实战1

目录 1 实战内容 2 确定思路 3 代码实操 3.1 实现一个个网页的爬取 3.2 爬取每一个网页的电影详情页url ​编辑 3.3 连接链接&#xff0c;针对每个详情页链接进行爬取、汇总内容 3.4 存储在txt文件中 4 结尾&#xff1a;整体代码 1 实战内容 爬取Scrape | Movie中所有…