C语言中一些有关字符串的常见函数的使用及模拟实现(2)

news2024/11/22 21:07:21

在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了\n⼀系列库函数,接下来我们就学习⼀下这些函数。

在上一篇博客中已经讲解了strlen,strcpy,strcmp,stccat这几个字符串相关的函数。
接着,再为大家介绍几个库函数,

strncpy,strncat,strncmp
同样包含在头文件string.h中
这三个函数都只是在中间加了个”n“,现在,来详细认识一下这三个库函数。

文章目录

  • strncpy函数
  • strncat函数
  • strncmp函数
  • strstr函数
  • memcpy函数

strncpy函数

看名字就知道,strncpy函数与strcpy函数是比较相似的,都是将一个字符串拷贝到另一个字符串中,不一样的是strncpy参数中多一个size_t类型的参数

在这里插入图片描述

这个参数的意思就是限制这个字符串的拷贝

在这里插入图片描述
这个例子就表示拷贝前5个字符,

来模拟实现一下这个库函数。

//strncpy的函数模拟实现
#include<stdio.h>
#include<assert.h>


char* my_strncpy(char* s1,const char* s2,size_t n)
{
	assert(s1 && s2);
	char* ret = s1;
	while (n--&&(*s1 = *s2))
	{
		s1++;
		s2++;
	}
	return ret;
}




int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "ghijk";
	char*ret = my_strncpy(arr1, arr2, 3);
	printf("%s", ret);
	return 0;
}

strncat函数

相信你在了解了strncpy函数之后,就大概可以猜出来strncat函数就是有限制的去追加一个字符串

在这里插入图片描述
看一个例子帮助理解
在这里插入图片描述

直接来看代码实现吧。

char* my_strncat(char* s1, char* s2, size_t n)
{
	assert(s1 && s2);
	char* ret = s1;
	while (*s1 != '\0')
	{
		s1++;
	}
	while (n-- && (*s1 = *s2))
	{
		*s1++;
		*s2++;
	}
	return ret;
}


int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "ghijk";
	char*ret = my_strncat(arr1, arr2, 1);
	printf("%s", ret);
	return 0;
}

strncmp函数

⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.

在这里插入图片描述

看上面这个例子,因为只比较了前四个字符,是相等的,所以返回0

在这里插入图片描述
该函数的返回类型是int类型。

来看一下这个函数的模拟实现

#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* str1, const char* str2,size_t num)
{
	int ret = 0;
	assert(str1 != NULL);
	assert(str2 != NULL);
	while (*str1 == *str2&&num--)
	{
		if (num == 0)
		{
			return 0;
		}
		str1++;
		str2++;
	}

	return *str1 - *str2;
}

int main()
{
	char arr1[10] = "abcdef";
	char arr2[10] = "abcdfg";
	int ret = my_strncmp(arr1,arr2,3);
	printf("%d", ret);
	return 0;
}

strstr函数

strstr函数是字符串中寻找子字符串的一个库函数。该函数的返回类型是char*类型,返回的是找到子字符串的第一个元素的地址,例如,在abcdef中查找一个cde,返回字符c的地址。
在这里插入图片描述

在这里插入图片描述
该函数返回类型是char*类型。

这个函数的模拟实现比之前略微增加一些难度,比如你在abcccdef中查找ccd,别慌,我们有解决方案,只需要做一个标记,下一次查找时直接从标记的下一个字符开始查找

char* my_strstr(const char* s1, const char* s2)
{
	assert(s1 && s2);//asser断言检查s1,s2是否是空指针
	char* cur = s1;//cur作为一个标记
	char* a1 = NULL;
	char* a2 = NULL;

	while (*cur)//cur到'\0'是还没有找到子字符串则返回空指针NULL。
	{
		a1 = cur;//从第二个字符开始遍历查找
		a2 = s2;
		while (*s1&&*s2&&*a1 == *a2)
		{
			*a1++;
			*a2++;
		}
		if (*a2 == '\0')//子字符串到'\0'时,表示找到了,返回指针cur
			return (char*)cur;
		cur++;
	}
	return NULL;
}

memcpy函数

在这里插入图片描述
这个函数又比strncpy函数高级了一点,它的参数和返回类型都都是void类型的,表示这不仅可以拷贝字符串,也可以拷贝数字数组了。

如下:

在这里插入图片描述来看一下它的模拟实现

void* my_memcpy(void* s1, const void * s2, size_t n)
{
	assert(s1 && s2);
	void* ret1 = s1;
	while (n--)
	{
		*(char*)s1 = *(char*)s2;
		*((char*)s1)++;
		*((char*)s2)++;
	}
	return ret1;
}

我们自己模拟实现的函数能否自己拷贝自己呢?
在这里插入图片描述
很明显,这是与我们想达到的效果是不一样的,它不能自己拷贝自己。
原因是当把1,2拷贝到3,4上时,3,4被改变成了1,2.所以不能自己拷贝自己。
但是库函数可以实现这个功能。
在这里插入图片描述
但是memcpy函数本身就没有要求自己拷贝自己,所以,我们的函数模拟实现还是没有问题的。
可以说编译器实现的库函数还是很厉害的。

C语言也有一个专门用来自己拷贝自己的库函数memmove
这里我们把模拟实现的代码放在这里,感兴趣的可以看一看。

从前向后拷贝和从后向前拷贝的方式时不一样的,所以要分类讨论一下

void* my_memmove(void* dest, const void* str, size_t n)
{
	assert(dest && str);
	void* ret = dest;
	if (dest < str)
	{
		while (n--)
		{
			*((char*)dest) = *((char*)str);
			(char*)dest = (char*)dest + 1;
			(char*)str = (char*)str + 1;
		}
	}
	else
	{
		while (n--)
		{
			*(((char*)dest)+n) = *(((char*)str)+n);
		}
	}
	return ret;
}

这就是几个字符串的简单讲解了,希望你能通过我的文章收获一些知识。

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

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

相关文章

java+springboot实验室管理系统的设计与实现ssm+jsp

课题研究内容&#xff1a; &#xff08;1&#xff09; 系统需求分析&#xff08;构成模块&#xff0c;系统流程&#xff0c;功能结构图&#xff0c;系统需求&#xff09; &#xff08;2&#xff09; 实验室课程安排功能模块&#xff08;课程的录入和调补&#xff09; &#xff…

浅聊langchain-chatchat

个人的一点经验和总结&#xff0c;希望能帮助到大家。有不对的地方请留言和指正&#xff01; langchain-GLM是什么 langchain-GLM是一个本地知识库应用解决方案&#xff0c;支持以cli、web、api方式提供以本地知识库或在线资源为知识素材的对话服务&#xff0c;对中英文场景对…

如何通过降低设备六大损失帮助企业改善OEE

在各个行业中&#xff0c;改善设备综合效率OEE&#xff08;Overall Equipment Efficiency&#xff09;是企业实现高效生产和竞争优势的关键。然而&#xff0c;设备的六大损失常常影响着企业的OEE指标。本文将探讨如何通过降低这六大损失来帮助企业改善OEE&#xff0c;提高生产效…

GCN01——Ubuntu中设置vivado编辑器为vscode

确定vscode位置 在命令行中输入 which code得到文件地址 进入文件夹后可看到&#xff0c;这是个链接文件&#xff0c;不过无所谓&#xff0c;就用这个地址就行 设置Text Editor 打开setting选择右侧text editor 这里说明了如何进行设置 将自己的地址加进去就行 /usr/share…

分布式架构demo

1、外层创建pom 版本管理器 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.15</version><relativePath/> <!-- lookup parent from repository…

VIR-SLAM代码分析3——VIR_VINS详解之estimator.cpp/.h

前言 续接上一篇&#xff0c;本本篇接着介绍VIR-SLAM中estimator.cpp/.h文件的函数&#xff0c;尤其是和UWB相关的相比于VINS改动过的函数&#xff0c;仍然以具体功能情况代码注释的形式进行介绍。 重点函数介绍 优化函数&#xff0c;代码是先优化&#xff0c;后边缘化。 …

Linux 系统渗透提权-Server2204

B-3:Linux 系统渗透提权 任务环境说明: 服务器场景:Server2204(关闭链接) 用户名:hacker 密码:123456 1.使用渗透机对服务器信息收集,并将服务器中 SSH 服务端口号作为 flag 提 交; Flag:2283/tcp

【Android】解决安卓中并不存在ActivityMainBinding

安卓中并不存在ActivityMainBinding这个类&#xff0c;这个类是在XML布局的最外层加入就会自动生成。但是你在最后绑定主布局时会报错获取不到根节点getRoot(). 最好的办法就是&#xff0c;删除原来的最外层节点&#xff0c;再重新添加&#xff0c;感觉是因为复制时并没有让系…

如何让嵌入式开发板使用主机的网络

配置网络 1.开发板配置 将开发板和主机用网线连接 安装 net-tools&#xff0c;使用 ifconfig 命令 或者使用 ip 命令 su root ip a 发现一个 eth0的网口 ip link set xxx up 有多个网口时可以用该命令启用某一个网口 vim /etc/netplan/00-installer-config.yaml写入以下…

看一看什么是AI PC:人工智能电脑

大家好啊&#xff0c;我是董董灿。 今天在一个群聊里&#xff0c;聊到了关于 AI PC (人工智能电脑)的话题。 之前看到过关于 AI PC 的新闻&#xff0c;说的是联想集团董事长兼CEO杨元庆在一次演讲中提到了 AI PC 的概念&#xff0c;并且绘声绘色的描绘了AI PC 的发展前景。 下…

传统算法: Pygame 实现快速排序

使用 Pygame 模块实现了快速排序的动画演示。首先,它生成一个包含随机整数的数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过快速排序算法对数组进行排序,动画效果可视化每一步的排序过程。在排序的过程中,程序选择一个基准元素(pivot),将数组分成两部分,…

知识图谱最简单的demo实现

一、简介 知识图谱整个建立过程可以分为以下几点&#xff1a; #mermaid-svg-zJuLB8k8EgBQF8M0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zJuLB8k8EgBQF8M0 .error-icon{fill:#552222;}#mermaid-svg-zJuLB8k8E…

Java实现简单的王者荣耀游戏

一、创建新项目 首先创建一个新的项目&#xff0c;并命名为wangzherongyao。 其次在飞翔的鸟项目下创建一个名为img的文件夹用来存放游戏相关图片。详细如下图&#xff1a; 二、游戏代码 1、创建怪物类 1.bear&#xff1a; package beast;import wangzherogyao.GameFrame;…

代码随想录算法训练营第三十七天 _ 贪心算法_738.单调自增的数字、968.监督二叉树

学习目标&#xff1a; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 738.单调自增的数字 听不懂的时候就到该动手了。必须要从后向前操作&#xff0c;才能把压力逐级传给最前面的这一位。入如&#xff1a;322 class Solution {// java中的String不能修改&#xf…

TQ2440开发板-LED全亮全灭控制程序设计

目录 什么是GPIOS3C2440的GPIO访问和控制方式&#xff1a;3种寄存器 TQ2440的LED灯底板原理图---LED测试部分核心板原理图----GPIO部分 LED控制---设计思想整体代码 && 代码研读配置GPIO端口为输出模式控制LED的全亮和全灭 真就是从零学起。 什么是GPIO GPIO&#xff…

SQL 金额数值转换成中文大写

需求&#xff1a;将金额转换成中文大写格式填入单据合计行&#xff1a; _佰_拾_万_仟_佰_拾_元_角_分 1234567.89 壹佰贰拾叁万肆仟伍佰陆拾柒元捌角玖分 1.函数转换 drop function n2C;CREATE FUNCTION n2C (num numeric(14,2)) RETURNS VARCHAR(20) AS BEGIN …

elementui中添加开关控制

<template><!-- 图层管理 --><div class"home-wrapper"><div class"table-list"><div class"list"><el-table :data"tableData" height"100%" style"width: 100%;" border>&…

系列十三、SpringBoot的自动配置原理

一、概述 我们知道Java发展到现在功能十分的强大&#xff0c;生态异常的丰富&#xff0c;这里面离开不了Spring及其家族产品的支持&#xff0c;而作为Spring生态的明星产品Spring Boot可以说像王者一般的存在&#xff0c;那么的耀眼&#xff0c;那么的光彩夺目&#xff01;那么…

BLP9H10-30GZ LDMOS 功率晶体管 Ampleon

BLP9H10-30GZ 30W塑料LDMOS 功率晶体管&#xff0c;适用于频率范围为616 MH 至960 MHz的基站应用。 BLP9H10-30GZ 特点和优势&#xff1a; 高效率 出色的耐用性 专为宽带操作而设计 出色的热稳定性 高功率增益 集成ESD保护 有关 RoHS 合规性 BLP9H10-30GZ应用程序&…

4.5-容器之间的link

我们在实际项目中可能会有种需求&#xff0c;假如我们有个后台项目&#xff0c;它要访问数据库&#xff0c;比如MySQL&#xff0c;它想要访问数据库&#xff0c;就需要数据库的ip和端口。如果有两个容器&#xff0c;一个容器启动的是数据库的MySQL服务&#xff0c;另一个容器启…