C语言模拟实现字符串处理函数

news2024/11/27 8:37:56

需要多一点点勇气,来面对变差的自己

大家好,我是纪宁。

这篇文章为大家带来的是5大字符串处理函数的模拟实现。

文章目录

1.strlen函数的模拟实现 

2.strcpy函数的模拟实现

3.strcmp函数的模拟实现

4.strcat函数的模拟实现

5.strstr函数的模拟实现


1.strlen函数的模拟实现 

  strlen函数的作用是求字符串的长度

  strlen的函数原型

常规方法

  找 ‘\0’ ,将字符串首地址传递过来,解引用后的值不是‘\0’的话,指针位置就后移,同时计数器count加1,知道指针解引用后的值为‘\0’,循环停止,函数返回计数器count的值

size_t my_strlen(char* str)
{
	size_t count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char str[1000] = "I have a my_strlen hanshu";
	size_t len = my_strlen(str);
	printf("%zu", len);
	return 0;
}

指针减指针

  将字符串首元素地址传过来之后,先用字符指针保存,再将保存的指针移动,找‘\0’,找到‘\0’后,用这个位置的指针减去字符串首元素地址即为字符串长度

  指针减去指针得到的值为两指针之间的元素个数

size_t my_strlen(char* str)
{
	char* str2 = str;
	while (*str2 != '\0')
		str2++;
	return str2 - str;
}
int main()
{
	char str[1000] = "I have a my_strlen hanshu";
	size_t len = my_strlen(str);
	printf("%zu", len);
	return 0;
}

递归

  递归方法的核心就是大事化小

  但要注意递归必须有条件,并且每次递归都要越来越接近这个条件

  当传递过来的指针解引用为‘\0’时,说明递归结束,否则就指针后移继续递归

size_t my_strlen(char* str)
{
	if (*str == '\0')
		return 0;
	else
		return my_strlen(str + 1) + 1;
}
int main()
{
	char str[1000] = "I have a my_strlen hanshu";
	size_t len = my_strlen(str);
	printf("%zu", len);
	return 0;
}

2.strcpy函数的模拟实现

  strcpy函数的作用是拷贝字符串

  strcpy的函数原型

注意事项:

  •   拷贝字符串,必须将 ‘\0’ 也拷贝过去 
  •   目表字符串必须是可变的,不能是常量字符串
  •   函数要返回目标字符串的首地址,所以要先将首地址存起来
#include<assert.h>
char* my_strcpy(char* str1, const char* str2)
{
	assert(str1 && str2);
	char* ret = str1;
	while (*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = *str2;
	return str1;
}
int main()
{
	char str1[100] = { "0" };
	char str2[100] = "my_strcpy hanshu";
	my_strcpy(str1, str2);
	return 0;
}

3.strcmp函数的模拟实现

  strcmp函数的作用是字符串比较

  strcmp函数原型

 注意事项:

  当str1>str2时返回一个大于0的数,str1<str2时返回一个小于0的数,str1=str2时返回0,所以模拟实现时,当str1!=str2时,可以用 *str1-*str2 来表示返回值

//实现strcmp函数
#incldue<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 && *str2)
	{
		if (*str2 == *str1)
		{
			str1++;
			str2++;
		}
		else
			return *str1 - *str2;
	}
	if (*str1 == *str2 && *str1 == '\0')
		return 0;
}
int main()
{
	char str1[100] = "abcdefg";
	char str2[100] = "abcdefr";
	if (my_strcmp(str1, str2) > 0)
		printf("str1>str2\n");
	else
		printf("str2>str1\n");
	return 0;
}

4.strcat函数的模拟实现

  strcat函数的作用是实现字符串的连接

  strcat函数原型

   实现strcat函数的时候,要先找到‘\0’,然后再模仿字符串拷贝函数的实现将字符串拷贝过去即可,且‘\0’也必须拷贝过去

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str1, const char* str2)
{
	assert(str1&&str2);
	char* ret = str1;
	//先找str1的  \0
	while (*++str1)
		 ;
	//将str2拷贝过来
	while (*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = *str2;
	return ret;
}
int main()
{
	char arr1[100] = "jining ";
	char arr2[100] = "bu shi da yuan zhong";
	my_strcat(arr1, arr2);
	printf("%s", arr1);
	return 0;
}

5.strstr函数的模拟实现

  strstr函数的作用是在字符串中找子字符串

  strstr函数原型

实现strstr函数要设置两重循环,外层循环控制目标字符串的指针位置,判断是否有指针解引用后与子字符串的首字符相同,若相同,再用内层循环判断子字符串是否为目标字符串的一部分

#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
	char* str3 = str1;
	int i = 0;
	for (i = 0; i < strlen(str1); i++)
	{
		int count = 1;
		if (*(str3 + i) == *str2)
		{
			int j = 0;
			for (j = 1; j < strlen(str2); j++)
			{
				if (*(str3 + i + j) == *(str2 + j) && *(str2 + j) != '\0')
					count++;
			}
			if (count == strlen(str2))
				return (str1 + i);
		}
	}
	return NULL;
}
int main()
{
	char str1[100] = "zyb is a big yuanzhong is zyb TT";
	char str2[100] = "ong";
	char* ret = my_strstr(str1, str2);
	printf("%s", ret);
	return 0;
}

在这里插入图片描述

  博主写了好长时间,如果你能给博主一个免费三连鼓励一下博主的话,那么我觉得你真是 泰     裤    辣 !!!

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

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

相关文章

相机标定-基础(一)

1. 何为相机标定? 当相机拍摄照片时,我们看到的图像通常与我们实际看到的不完全相同。这是由相机镜头引起的,而且发生的频率比我们想象的要高。 这种图像的改变就是我们所说的畸变。一般来说,畸变是指直线在图像中出现弯曲或弯曲。 这种畸变我们可以通过相机标定来进行解…

反常积分题目

目录 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a;​ 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; 我们首先引入反常积分的定义&#xff1a; CSDNhttps://mp.csdn.net/mp_blog/creation/editor/131676865 题目1&#xff1a; 题目2…

STM32 ws2812b多屏驱动程序

文章目录 前言一、ws2812b的数据传输以及屏幕的组合二、代码ws2812screen.c文件ws2812screen.h文件主函数 前言 在上篇文章中使用了stm32的dmatim的方式点亮了ws2812b的灯 但是我的需求不仅仅是点亮他&#xff0c;我需要他像屏幕一样显示某一些东西&#xff0c;ws2812显示有一…

深入学习 Redis - 全局命令、过期策略如何实现、高效定时器原理

目录 Redis 全局命令 get 和 set keys keys 使用注意事项 exists exists 使用注意事项 del del 使用注意事项 expire 【面试经典】redis 中 key 的过期策略是怎么实现的&#xff1f; 定时器实现原理&#xff08;非 Redis 实现&#xff0c;拓展&#xff09; 1.基于 …

21 - 队列 - 循环队列——队列的顺序表示和实现

前面我们学习数组队列,链式队列,我们今天来学习循环队列。 队列的定义 队列(Queue)也是一种线性表, 但是它仅能在一端进行插入,而另一端进行删除的操作 ,插入的一端称为 队尾rear,删除的一端称为 队头front 。 向一个栈插入新元素又称作进队或入队, 从一个栈删除元素…

从实体按键看 Android 车载的自定义事件机制

在汽车数字化、智能化变革的进程中&#xff0c;越来越多的车机设计或部分、或全部地舍弃了实体按键&#xff0c;进而把车主操作的入口转移到了车机 UI 以及语音助手。 但统一、高效的零层级 UI 颇为困难&#xff0c;语音的准确率、覆盖率亦不够完善&#xff0c;那么在当下的阶段…

【数据结构】文件的归并排序

目录 1、归并排序引申出的问题 2、磁盘与文件的关系---包含与被包含的关系 3、思路&#xff1a; 4、代码实现 1、归并排序引申出的问题 归并排序是最常用的外排序的方法&#xff08;但归并排序既可进行内部排序也可进行外部排序&#xff09;&#xff0c;外排序就是在磁盘中…

LLaMA(Open and Efficient Foundation Language Models )论文解读(二)

此篇博客主题:LLAMA模型数据、训练时长、功耗及碳排放量 LLaMA: Open and Efficient Foundation Language Models paper https://arxiv.org/pdf/2302.13971v1.pdf 1 训练样本 Overall, our entire training dataset contains roughly 1.4T tokens after tokenization. For mo…

2023年Q2京东厨卫大电市场分析报告(京东运营数据分析)

随着新产品推广和消费需求升级&#xff0c;今年Q2&#xff0c;京东厨卫大电市场的销售额突破百亿&#xff0c;从同环比来看均呈增长趋势。百亿市场中&#xff0c;油烟机、电热水器、燃气热水器这三大品类占据较大份额&#xff0c;这一期&#xff0c;我们重点来看一下京东厨卫大…

怎么用Postman脚本中发送请求

Postman的Collection(集合)/Folder(集合的子文件夹)/Request(请求)都有Pre-request script和Tests两个脚本区域, 分别可以在发送请求前和请求后使用脚本(基于Javascript实现各种操作) 在遇到有依赖的接口时,比如需要登录或者需要从前一个接口的结果中获取参数时,我们往往需要在…

vscode 调试(linux )

一、配置程序运行依赖 1, 打开配置文件&#xff08;launch.json) (1) 从工具栏打开Run–>Add Configuration… &#xff08;2&#xff09;查看配置文件&#xff08;launch.json&#xff09; 2&#xff0c;添加配置 (1) 配置可执行程序&#xff08;program&#xff09;…

ceph存储的应用

ceph存储的应用 一&#xff1a;创建 CephFS 文件系统 MDS 接口1.服务端操作1&#xff09;在管理节点创建 mds 服务2&#xff09;查看各个节点的 mds 服务3&#xff09;创建存储池&#xff0c;启用 ceph 文件系统4&#xff09;查看mds状态&#xff0c;一个up&#xff0c;其余两个…

reggie优化01-缓存短信验证码和菜品数据

1、缓存短信验证码 1.1 Redis配置类RedisConfig 在config包下&#xff0c;创建Redis配置类RedisConfig&#xff1a; 纳入Git管理&#xff1a; package com.itheima.reggie.config;import org.springframework.cache.annotation.CachingConfigurerSupport; import org.sprin…

接口自动化测试框架unittest和pytest差异比较

前言 说到 Python 的单元测试框架&#xff0c;想必接触过 Python 的朋友脑袋里第一个想到的就是unittest。 的确&#xff0c;作为 Python 的标准库&#xff0c;它很优秀&#xff0c;并被广泛用于各个项目。但你知道吗&#xff1f;其实在 Python 众多项目中&#xff0c;主流的单…

【ROS机械臂入门教程】

首先声明一下&#xff0c;此项目是参考B站哈萨克斯坦UP的【ROS机械臂入门教程】&#xff0c;前期以复现【机械臂视觉抓取从理论到实战】 此内容为他研究生生涯的阶段性成果展示和技术分享&#xff0c;所有数据和代码均开源。所以鹏鹏我又特此来复现一下&#xff0c;我采用的硬件…

Redis源码篇 - Reactor设计模式 和 Redis Reactor设计模式

Reactor &#xff1a;反应器模式或者应答者模式&#xff0c;它是一种基于事件驱动的设计模式。拥有一个或者多个输入源&#xff0c;通过反应器分发给多个worker线程处理&#xff0c;实现并发场景下事件处理。 此图网上找的&#xff0c;画的很好&#xff1a;

中国新一代载人运载火箭“长征十号”发布,衍生型号积极研发中

我国新一代载人运载火箭“长征十号”已发布&#xff0c;主要用于将月面着陆器和登月飞船送入地月转移轨道。此外&#xff0c;“长征十号”还有一个衍生型号正在积极研发中。根据中国运载火箭技术研究院官方消息&#xff0c;近期&#xff0c;火箭院北京强度环境研究所圆满完成了…

SQlite3数据库相关相关命令

1&#xff09;系统命令 以 ‘.’ 开头 .help 帮助手册 .exit 退出 .table 查看当前数据库的有的表格名 .databases .schema 查看表的结构属性2&#xff09;sql语句 以 ;结尾 1. 创建表格 create table <table-name> (id integer, age integer, name char, score f…

夜深人静学32系列18——DMA+ADC单/多通道采集

夜深人静学32系列18——DMAADC单/多通道采集 DMA & ADC (理论篇)DMADMA框图DMA通道与外设对应表 ADC重要知识不同模式组合的作用 为什么要是用DMA ADC&#xff1f;DMA & ADC (实战篇)任务要求原理图CubeMX配置代码实现实验现象 很久没更新了&#xff0c;这次我们浅浅的…

MVSNet、PatchMatchNet环境配置、运行演示

文章目录 1 环境配置要求2 配置流程2.1 创建新环境mvs环境2.2 配置 PatchMatchNet环境3 程序运行演示1 环境配置要求 Ubuntu 18.04 python 3.7 , CUDA 10.1。 requirements.txt torch==1.4.0 torchvision==0.5.0 opencv-python numpy plyfile pillow tensorboard以上环境MV…