字符串函数的模拟实现(strlen,strcpy,strcat,strcmp,strstr)(图文并茂,清晰易懂)

目录

  • 1. strlen函数
  • 2. strcpy函数
  • 3. strcat函数
  • 4. strcmp函数
  • 5. strstr函数

个人专栏

《零基础学C语言》

1. strlen函数

strlen函数(Get string length)的功能是求字符串长度

使用注意事项

  1. 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
  2. 参数指向的字符串必须要以 ‘\0’ 结束。
  3. 注意函数的返回值为size_t,是无符号的(易错

在这里主要讲解三种方法模拟实现

  • 方法一
  • 计数器
size_t my_strlen1(const char* str)
{
	assert(str);
	int count = 0;

	while (*str++)
	{
		count++;
	}

	return count;
}
  • 方法二
  • 指针-指针
  • 得到的是中间元素的个数

这里我们要记录下字符串的初始位置,等str移动到 ‘\0’ 后,相减得结果

size_t my_strlen2(const char* str)
{
	assert(str);
	char* start = str;

	while (*str)
	{
		str++;
	}

	return str - start;
}
  • 方法三
  • 递归

递归主要考虑返回条件子问题

  1. 返回条件:如果str指向 ‘\0’ ,则返回0
  2. 子问题:转化为求my_strlen(str+1) (除去本身字符的字符串)+ 1(本身字符)
size_t my_strlen3(const char* str)
{
	assert(str);

	if (*str == '\0')
	{
		return 0;
	}

	return my_strlen3(str + 1) + 1;
}

运行结果:

void TestMyStrlen()
{
	char arr[] = "abcdef";
	size_t len = my_strlen3(arr);
	printf("%zd\n", len);
}

2. strcpy函数

strcpy函数(Copy string)的功能是字符串拷贝

  • 将源字符串拷贝到指定空间

使用注意事项

  1. 源字符串必须以 ‘\0’ 结束。
  2. 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  3. 目标空间必须足够大,以确保能存放源字符串。
  4. 目标空间必须可修改。
  5. 返回值是目标空间的地址

下面代码最巧妙的地方,在于把字符串的拷贝和 ‘\0’ 的拷贝融合在一起。循环中,先赋值,再判断,最后++。这样就算遇到 ‘\0’ ,也会先拷贝,再判断停止。

char* my_strcpy(char* dst, const char* src)
{
	assert(dst && src);
	char* ret = dst;

	while (*dst++ = *src++)
	{
		;
	}

	return ret;
}

运行结果:

3. strcat函数

strcat函数(Concatenate strings)的功能是字符串追加

  • 将一段字符串追加到另一段字符串后面

使用注意事项

  1. 源字符串必须以 ‘\0’ 结束。
  2. 目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。
  3. 目标空间必须有足够的大,能容纳下源字符串的内容。
  4. 目标空间必须可修改。
  5. 返回值是目标空间的地址

字符串追加可以理解为两个过程:

  1. 找到目标字符串末尾的 ‘\0’
  2. 开始追加(其实就是字符串拷贝)
char* my_strcat(char* dst, const char* src)
{
	assert(dst && src);
	char* ret = dst;

	while (*dst)
	{
		dst++;
	}

	while (*dst++ = *src++)
	{
		;
	}

	return ret;
}

运行结果:

4. strcmp函数

strcmp函数(Compare two strings)的功能是字符串比较

  • 比较两个字符串是否相等
  • 如果相等,则返回0
  • 那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小。

使用注意事项

  1. 不是比较两个字符串的长度(极其易错
  2. 一般我只用来判断两个字符串是否相等,至于不相等时,比较字符之间大小,我感觉还没遇到很好的应用
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;
}

运行结果:



5. strstr函数

strstr函数(Locate substring)的功能是查找子串

  • 在字符串str1中查找是否存在与str2相等的子串
  • 如果存在,则返回该地址(返回字符串str2在字符串str1中第⼀次出现的位置)
  • 如果不存在,则返回空指针

使用注意事项

  1. 如果要查找的子串为空串,则直接返回str1的地址

我们这里采用最直观,容易理解的暴力求解法

  1. 额外设立cur,dst,src三个指针
  2. 如果子串为空,则直接返回str1
  3. 如果str1为空,则直接返回NULL
  4. 如果不满足以上情况,则进入大循环:每次循环开始,让dst指向cur所在的位置,src指向str2(子串)
  5. 如果*dst == *src,则继续向后比较;如果不相等,则跳出小循环,判断src是否为 ‘\0’,如果为 ‘\0’ ,则代表匹配成功,返回地址cur
  6. 如果不为 ‘\0’,则代表当前位置往后没有可匹配的项,则cur++,继续重复以上循环
  7. 若以上循环结束,还没有找到对应子串,则返回NULL

是不是光看文字还不理解,我们来看图分析

首先,(假设dst是s1,src是s2),cur从a开始,s1和s2比较,不相等,再判断s2是否为’\0’,不为0,则cur++

cur再从b开始比较,s1和s2相等,则继续比较

直到s1和s2不相等,再判断s2是否为’\0’,不为0,则cur++

cur再从下一个b开始,同样重复以上步骤……

s2还是不为0,cur++

cur从第三个b开始,s1和s2比较。

这次,直到s1和s2不相等时,s2终于为’\0’,则代表匹配成功,返回地址cur!!!

//暴力求解
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* cur = str1;
	const char* dst = NULL;
	const char* src = NULL;

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

	while (*cur)
	{
		dst = cur;
		src = str2;

		while (*dst == *src)
		{
			dst++;
			src++;
		}

		if (*src == '\0')
		{
			return (char*)cur;
		}

		cur++;
	}

	return NULL;
}

运行结果:



这种暴力求解的方法比较好理解,但效率却不是很高。其实还有一种高效求子串的方法——KMP算法,在后期会跟大家进行详细讲解。

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!
💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

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

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

相关文章

品牌线上窜货查的出来吗

如果窜货不治理会出现什么局面,显见的当然是渠道混乱,低价丛生,严重的还会导致真假混卖,最后所有的后果都会由品牌承担,口碑的影响是必然的,那品牌的衰败也会是一种趋势,所以治理窜货是品牌发展…

毛里塔尼亚市场开发攻略,收藏一篇就够了

毛里塔尼亚是非洲西北部的一个国家,也是中国长期援建的一个国家,也是一带一路上的国家。毛里塔尼亚生产生活资料依赖进口,长期依赖跟我们国家的贸易关系也是比较紧密的,今天就来给大家介绍一下毛里塔尼亚的市场开发公路。文章略长…

vue2【组件的构成】

目录 1:什么是组件化开发 2:vue中的组件化开发 3:vue组件的三个组成部分 4:组件中定义方法,监听器,过滤器,计算属性节点。 5:template中只允许唯一根节点,style默认…

二次开发问题汇总【C#】

1未将对象引用到实例。 接口函数的参数不对。解决办法【用fixed去限制数组长度】 unsafe public struct VCI_BOARD_INFO {public UInt16 hw_Version;public UInt16 fw_Version;public UInt16 dr_Version;public UInt16 in_Version;public UInt16 irq_Num;public byte can_Num;…

高浓度化工废水如何处理

高浓度化工废水的处理一直是一个备受关注的社会问题。随着化工行业的不断发展,化工废水的排放量也逐渐增加。因此,我们需要找到一种有效的方法来处理这种高浓度化工废水,以保护环境和人民的健康。 首先,我们可以采用物理方法处理…

基于springboot实现农机电招平台系统项目【项目源码+论文说明】

基于springboot实现农机电招平台系统演示 摘要 随着农机电招行业的不断发展,农机电招在现实生活中的使用和普及,农机电招行业成为近年内出现的一个新行业,并且能够成为大群众广为认可和接受的行为和选择。设计农机电招平台的目的就是借助计算…

2015年7月28日 Go生态洞察:GopherCon 2015综述

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

选择振弦采集仪:易操作、快速数据传输和耐用性是关键要素

选择振弦采集仪:易操作、快速数据传输和耐用性是关键要素 振弦采集仪是一种可以测量和记录振动、冲击、声音等信号的设备。它是目前工程、科研、医学、环保等领域中常见的一种测试设备。在选择振弦采集仪时,易操作、快速数据传输和耐用性是关键要素。 易…

VUE项目部署过程中遇到的错误:POST http://124.60.11.183:9090/test/login 405 (Not Allowed)

我当初报了这个405错误,再网上查了半天,他们都说什么是nginx部署不支持post访问静态资源。 但后面我发现我是因为另一个原因才导致的无法访问。 我再vue中有使用devServer:{ proxy:{} }进行路由转发。 但是!! 在这个配置只…

《洛谷深入浅出基础篇》P4715淘汰赛——二叉树

上链接:【深基16.例1】淘汰赛 - 洛谷https://www.luogu.com.cn/problem/P4715 上题干: 题目描述 有 2^n(n≤7)个国家参加世界杯决赛圈且进入淘汰赛环节。已经知道各个国家的能力值,且都不相等。能力值高的国家和能力值…

YOLOv5 分类模型 预处理 OpenCV实现

YOLOv5 分类模型 预处理 OpenCV实现 flyfish YOLOv5 分类模型 预处理 PIL 实现 YOLOv5 分类模型 OpenCV和PIL两者实现预处理的差异 YOLOv5 分类模型 数据集加载 1 样本处理 YOLOv5 分类模型 数据集加载 2 切片处理 YOLOv5 分类模型 数据集加载 3 自定义类别 YOLOv5 分类模型…

逻辑回归

目录 第1关:逻辑回归核心思想 相关知识 什么是逻辑回归 编程要求 代码文件 第2关:逻辑回归的损失函数 相关知识 为什么需要损失函数 逻辑回归的损失函数 题目答案 第3关:梯度下降 相关知识 什么是梯度 梯度下降算法原理 编程要…

电线电缆、漆包线工厂开源MES/生产管理系统/云MES

万界星空科技专业的漆包线MES系统功能介绍: 从原材料出入库-拉丝机等设备管理-漆包线称重打印系统自动入库(支持多台秤同时称重)-建立销售报价、销售订单-生产订单-支持扫码出库及自动拣货出库-应收应付账款-对接各种其他系统及财务系统。 …

(免费领源码)java#springboot#mysql流浪动物救助系统78174-计算机毕业设计项目选题推荐

摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存…

NX二次开发UF_CURVE_add_string_to_ocf_data 函数介绍

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_add_string_to_ocf_data Defined in: uf_curve.h int UF_CURVE_add_string_to_ocf_data(tag_t string_tag, int offset_direction, int num_offsets, UF_CURVE_ocf_values_…

芯片的测试方法

半导体的生产流程包括晶圆制造和封装测试,在这两个环节中分别需要完成晶圆检测(CP, Circuit Probing)和成品测试(FT, Final Test)。无论哪个环节,要测试芯片的各项功能指标均须完成两个步骤:一是将芯片的引脚与测试机的功能模块连接起来&…

一些好用的前端小插件(转自知乎)

一些好用的前端小插件(2) 1. cropper.js Cropper.js 2.0 是一系列用于图像裁剪的 Web 组件。 官网地址:https://fengyuanchen.github.io/cropperjs/v2/zh/ 2. Vditor Vditor是一款浏览器端的 Markdown 编辑器,支持所见即所得、…

点击按钮,按钮的文字变为倒计时,的小技巧(适用于获取验证码)

看效果图&#xff1a; 代码 <a-buttonclick"getSms":disabled"myState.smsSendFlag"v-text"(!myState.smsSendFlag && 获取验证码) || ${myState.time} s" ></a-button>data(){return {myState: {smsSendFlag: false,tim…

【【Linux 常用命令学习 之 一 】】

Linux 常用命令学习 之 一 打开终端之后的 我们会了解 所使用的 字符串含义 其中前面的 zhuxushuai 是 当前的用户名字 接下来的 zhuxushuai-virtual-machine 是 机器名字 最后的符号 $表示 当前是普通用户 输入指令 ls 是打印出当前所在目录中所有文件和文件夹 shell 操…

BUUCTF [WUSTCTF2020]find_me 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 感谢 Iven Huang 师傅供题。 比赛平台&#xff1a;https://ctfgame.w-ais.cn/ 密文&#xff1a; 下载附件&#xff0c;得到一个.jpg图片。 解题思路&#xff1a; 1、得到一张图…