字符串函数和内存函数详解(2)

news2024/11/17 7:46:50

🐵本文会将会对剩余的字符串库函数内存函数进行讲解

1.strstr📚

1.1函数用法✏️

strstr函数原型:

strstr用于在字符串中找子串,strstr会返回str1中出现str2的起始地址,如果在str1中没有找到str2,则返回空指针

1.2具体实现🖊️

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

int main()
{
	char arr1[] = "i like chess";
	char arr2[] = "like";

	char* ret = strstr(arr1, arr2); 
	if (ret != NULL)
	{
		printf("%s", ret);
	}
	else
	{
		printf("没找到");
	}

	return 0;
}

strstr会返回arr1中第一次出现arr2的地址,这里就是'l'的地址,将其传给指针ret,在打印时会从'l'处依次向后打印,结果为like chess;如果arr2是字符串"abc"的话,strstr就会返回空指针,打印结果为没找到

1.3模拟实现✍🏻

让str1和str2从第一个地址开始比较,如果相等那str1和str2都向后走一个字节,如果str1和str2一直相等,就应该返回str1中出现str2的起始位置,所以这里应该再来一个指针p用来保存str1和str2比较时str1的起始位置

如果str1和str2进行比较时遇到不相等的字符,就说明从p位置处开始不可能找到str2,所以应先让p向后走一个字节,再让str1回到p处,比如上图中,str1和str2从起始位置开始比较,'a'和'b'不相等,那就说明从p位置处开始不可能出现str2,那么p应该向后走一个字节,再让str1指向p所指的地址;str2应该回到它的起始地址,这里应再定义两个个指针s1,s2,让str1和str2不变,让s1和s2进行比较

总结:如果相等s1和s2一直想后走,当s2遇到'\0'时说明str1里有str2,返回p,如果不相等,p向后走一个字节,s1指向p,s2指向str2,直到相等返回p

代码:

#include<stdio.h>
#include<assert.h>

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* s1 = str1;
	char* s2 = str2;
	char* p = str1;
	while (*p)
	{
		if (*s1 == *s2)
		{
			s1++;
			s2++;
			if (*s2 == '\0')
			{
				return p;
			}
		}
		else
		{
			s2 = str2;
			p++;
			s1 = p;
		}
	}
	return NULL;
}

int main()
{
	char arr1[] = "abbcde";
	char arr2[] = "bcd";
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
	{
		printf("%s\n", ret);
	}
	else
	{
		printf("没找到\n");
	}
	return 0;
}

2.strtok📚

2.1函数用法✏️

strtok函数原型:

strtok用于分割字符串,delimiters指定一个字符串,该字符串中包含分割str的分隔符,而str也指定一个字符串,在该字符串中,包含一个或多个分隔符分割的标记

strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置
。比如:str指定的字符串是12345@qq.com,分隔符为@和.,第一个参数不为NULL,所以strtok会将第一个标记@改为\0,并记住这个位置,在第二次使用strtok时,可以将第一参数设为NULL,这样就会从上一次保存的位置开始找第二个标记
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标

如果字符串中不存在更多的标记,则返回 NULL 指针。
由于strtok函数回改变源字符串,所以在使用strtok函数前,会临时拷贝一份源字符串,对拷贝后的字符串使用strtok函数

2.2具体实现🖊️

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

int main()
{
	char arr[] = "1234@qq.com";
	char buf[20] = { 0 };
	strcpy(buf, arr);
	char* p = "@.";
	char* ret = NULL;
	for (ret = strtok(buf, p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}

	return 0;
}

for循环的初始化部分只会进行一次,这样第一次使用strtok时第一个参数是buf,之后第一个参数都是NULL,这样就能分割整个字符串

打印结果:

3.strerror📚

3.1函数用法✏️

strerror函数原型:

strerror用于返回错误码所对应的错误信息

3.2具体实现🖊️

sterror函数通常是在出现错误码时使用该函数查看错误码所对应的错误信息,并不会特意使用,这里只是举个例子:比如查看1~9所对应的错误信息:

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

int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		char*ret = strerror(i);
		printf("%d: %s\n", i, ret);
	}
	return 0;
}

以下是打印结果:

------内存函数------

接下来会讲解memcpy,memmove,memcmp函数,字符串函数比如strcmp只能比较两个字符串,strcpy也只能拷贝字符串,但是在内存中的数据并非只有字符串,所以引入内存函数可以操作任意类型的数据

4.memcpy📚

4.1函数用法✏️

memcpy函数原型:

用于拷贝内存数据,destination指定目标字符串,source指定源字符串,num是要拷贝的字节数

4.2具体实现🖊️

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

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[10] = { 0 };
	size_t num = 20; //将5个数全部拷贝到arr2,所以是20个字节
	memcpy(arr2, arr1, num);

	return 0;
}

通过调试观察,拷贝前:

拷贝后:

4.3模拟实现✍🏻

由于memcpy再拷贝时是一个字节一个字节拷贝的,所以应将des和src强转为字符指针,每完成一次拷贝就再强转为字符指针后+1,这样就能达到一个字节一个字节拷贝的目的

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* des, const void* src, size_t n)
{
	assert(des && src);
	void* ret = des;
	while (n--)
	{
		*(char*)des = *(char*)src;
		des = (char*)des + 1;
		src = (char*)src + 1;
	}
	return ret;
}

5.memmove📚

5.1函数用法✏️

memmove函数原型:

可以发现memmove和memcpy的函数原型一致,其实memmove和memcpy用法基本一样,差别就是当源空间和目标空间重叠时可以使用memmove;

比如说一个整形数组int arr[] = {1,2,3,4,5,6,7,8,9};将3~7的位置拷贝到1~5的位置时可以memmove

5.2具体实现🖊️

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

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8 };
	size_t num = 16;
	memmove(arr + 2, arr, num);

	return 0;
}

通过调试观察,拷贝前:

拷贝后:

5.3模拟实现✍🏻

如果按照memcpy函数模拟实现的方法来模拟实现的话,无法达到预期目的(假如是将2~5拷贝到4~7的位置处):

当将2和3分别拷贝到4和5的位置后,在接下来要将4拷贝到6的位置时就已经无法达到目的了,因为此时4的位置已经被2拷贝过,再去拷贝到6的位置时,实际上是将2拷贝6的位置,那么整个拷贝操作结束后该数组会变为1 2 3 2 3 2 3 8,在这种des在src之后的情况下可以将src从后往前拷贝,5->7,4->6,3->5,2->4,这样就能达到拷贝的目的

反之当des在src之前时,应将src从前往后拷贝,这种情况下的模拟实现和memcpy一致

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* des, const void* src, size_t n)
{
	assert(des && src);
	void* ret = des;
	if (des > src)
	{
		while (n--)
		{
			*((char*)des + n) = *((char*)src + n);
		}
	}
	else
	{
		while (n--)
		{
			*(char*)des = *(char*)src;
			des = (char*)des + 1;
			src = (char*)src + 1;
		}
	}
	return ret;
}

6.memcmp📚

6.1函数用法✏️

memcmp函数原型:

用于比较两个内存数据,ptr1和ptr2分别指定两个内存数据,num代表要比较的前num个字节

6.2具体实现🖊️

注意:这里比较的是前num个字节

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

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,5,6 };
	size_t num = 0;
	scanf("%zd", &num);

	int cmp = memcmp(arr1, arr2, num);
	if (cmp > 0)
	{
		printf("arr1 > arr2\n");
	}
	else
	{
		printf("arr1 <= arr2\n");
	}

	return 0;
}

7.memset📚

7.1函数用法✏️

memset函数原型:

memset用来设置内存的,ptr指向一个内存数据,value是要设置的值,num是要设置的字节数

7.2具体实现🖊️

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

int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'x', 5);
	printf("%s", arr); 打印结果:hello xxxxx

	int arr[10] = { 0 };
	memset(arr, 1, 40); //这里并不会将arr里面变为10个1,因为他是一个字节一个字节设置的
//所以它将每个字节设为了1,那么就变成了10个非常大的数
//综上所述,memset适合于字符数组,或者将整形数组全部设为0
	return 0;
}

🙉至此,字符串函数和内存函数全部讲解完毕!后续将会讲解结构体、联合、枚举相关内容

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

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

相关文章

FreeRTOS移植以及核心功能

文章目录 freertos和ucos区别&#xff0c;优缺点比较移植步骤核心功能内存管理&#xff08;5种内存管理策略&#xff09;FreeRTOS任务调度算法有三种时间管理通信管理 栈管理 freertos和ucos区别&#xff0c;优缺点比较 FreeRTOS&#xff08;Free Real-Time Operating System&…

jdk20 download 配置(linux window mac)

download 直达链接 jdk20,17 wget https://download.oracle.com/java/20/latest/jdk-20_linux-x64_bin.deb # 类似格式替换包的名称就可以实现终端下载jdk下载登录/oracle账号 下载jdk有可能存在要求登录帐号的情况 # 好心人的帐号 账号&#xff1a; 59968873qq.com 密码&…

数据库基本概念与安装MySQL数据库

MySQL数据库基本操作与简单管理 1、数据库的基本概述1.1数据库背景1.2数据库组成1.3数据库发展1.4数据库组成1.5数据库的数据流向1.6数据库功能1.7DBMS的工作模式 2、关系性数据库和非关系性数据库2.1关系型数据库2.2非关系型数据库2.3关系型数据库和非关系型数据库的区别 3、编…

“Vue进阶:深入理解插值、指令、过滤器、计算属性和监听器“

目录 引言&#xff1a;Vue的插值Vue的指令Vue的过滤器Vue的计算属性和监听器vue购物车案例总结&#xff1a; 引言&#xff1a; Vue.js是一款流行的JavaScript框架&#xff0c;它提供了许多强大的功能来简化前端开发。在本篇博客中&#xff0c;我们将深入探讨Vue的一些高级特性…

【计算机基础知识】计算机的概念

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言1.计算机的概念计算机的发展历程知识拓展&#xff1a; 计算机的特点计算机的分类 2.计算机的应用计算机的发展趋势知识拓展: 总结 前言 美…

双翌保养码使用指南方法三

保养码使用指南方法三&#xff1a;WiseAlign版本 为了保障您能够顺利使用软件&#xff0c;使之正常运行和合规使用&#xff0c;如何正确使用保养码显得尤为重要。以下是针对 WiseAlign软件的保养码使用指南&#xff0c;帮助您顺利进行激活操作。 步骤一&#xff1a;打开软件并…

uniapp:不同权限设置不同的tabBar

1、在pages.json里&#xff0c;将所有tabBar涉及的页面都加进来。 我这里使用username来动态显示tabBar。 jeecg用户显示&#xff1a;首页&#xff0c;订单&#xff0c;消息&#xff0c;发现&#xff0c;我的&#xff0c;一共5个tabBar。 admin用户显示&#xff1a;首页&…

喜报:项目验收季之陕西融通军民服务社会议室大屏系统项目建设顺利通过竣工验收

由达之云承建的陕西融通军民服务社会议室大屏系统项目建设日前完满完成各项建设任务&#xff0c;建设成果达到预期项目建设目标&#xff0c;并于9月19日顺利通过项目竣工验收。 陕西融通军民服务社有限公司会议大屏系统建设项目为大会议室增加一套视频会议系统&#xff0c;将原…

同为科技(TOWE)工业用插头插座及配电箱产品选型推荐

工业用插头插座及配电箱产品是专用于工业环境中的电源连接和电气设备控制&#xff0c;与普通家用插头插座相比&#xff0c;通常具有更高的功率和电流容量&#xff0c;并且设计上考虑了耐用性、安全性和适应各种环境条件的能力。工业用插头插座产品类型多样&#xff0c;包括插头…

【数仓建设系列之六】数仓管理利器-数据中台

【数仓建设系列之六】数仓管理利器-数据中台介绍 相信看过前面几篇数仓建设系列文章的同学已经对什么是数仓以及如何建设数仓有了充分的认知和了解了&#xff0c;那么问题很多的小明就要问了&#xff0c;既然数仓已经建设起来了&#xff0c;那企业如何管理运营数仓呢&#xff1…

WorkPlus打造智慧企业移动门户,开启高效办公新时代

在移动互联网时代&#xff0c;企业对于高效办公和便捷访问的需求不断增长。WorkPlus作为领先的品牌&#xff0c;致力于打造智慧企业移动门户&#xff0c;帮助企业实现高效协作与便捷访问。本文将重点介绍WorkPlus如何通过创新解决方案&#xff0c;为企业提供定制化的智慧移动门…

Python画图系列——折线图

好看的折线图 import numpy as np import matplotlib.pyplot as plt# 生成随机数据 # np.random.seed(42) # 设置随机种子以确保可重复性 sample_numbers np.arange(1, 21) # 生成1到20的样本编号random_data np.random.rand(20) # 生成20个随机数&#xff0c;范围在0到1之…

企业电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

文字处理工具 word 2019 mac中文版改进功能

Microsoft Word 2019 是微软公司的文字处理软件&#xff0c;是 office 2019 套件中的一部分。它是一个功能强大、易于使用的工具&#xff0c;可以帮助用户创建各种类型的文档&#xff0c;包括信函、简历、报告、手册等。 Word 2019 提供了许多功能和改进&#xff0c;包括更好的…

Day 02 python学习笔记

python运算符 算术运算符 混合运算的优先级&#xff1a; () > ** * / // % 高于 - 赋值运算符 - * / ** a 1 > a 3 > a a 3 其余同理 注意&#xff1a; python没有自增自减 &#xff08;a a a-- --a&#xff0…

华为技术有限公司副总裁、计算产品线总裁张熙伟一行到访湖南欧拉生态创新中心座谈交流

9月16日下午&#xff0c;华为技术有限公司&#xff08;简称&#xff1a;华为&#xff09;副总裁、计算产品线总裁张熙伟一行到访湖南欧拉创新中心开展座谈交流。麒麟信安董事长杨涛&#xff0c;麒麟信安高级副总裁刘坤、陈松政&#xff0c;副总裁王攀、颜跃进等参加交流。 华为…

【HTTP】Cookie 和 Session 详解

Cookie 和 Session 一. Cookie1. 什么是 Cookie2. Cookie 的作用3. Cookie 的组成4. Cookie 的组织形式5. Cookie 的传输6. 如何提高 Cookie 的安全性7. Cookie 类 二. Session1. 理解会话机制 (Session)2. Sessoin 的组织形式3. HttpSession 类 三. Cookie 和 Session 的联系与…

ATF编译报错,更新工具链后解决

同一个问题被两个人问到&#xff0c;都是ATF源码编译不过&#xff0c;更新工具链后解决 unknown value armv8.5-a’ for -march cc1: error: unknown value cortex-a55’ for -tune 如果您在编译的时候&#xff0c;也遇到架构或微架构的错误&#xff0c;可尝试更新工具链。 分…

家长监控孩子电脑屏幕的软件有哪些?怎么监控家中孩子的电脑?

在当今信息化社会&#xff0c;互联网已经成为孩子们学习、娱乐和社交的重要平台。然而&#xff0c;网络环境中充斥着各种不良信息和安全隐患&#xff0c;对孩子的身心健康造成了一定的影响。为了保障孩子的网络安全和健康成长&#xff0c;家长们需要采取一定的措施来监控孩子的…

01-初识HTML

01-初识HTML 学习目标&#xff1a; 理解HTML的基本语法掌握排版标签实现标题等效果相对路径和绝对路径媒体标签&#xff08;图片、音频、视频&#xff09;超链接 一、基础认知 了解网页组成和五大浏览器 明确Web标准的构成 1.1 认识网页 以下网页有哪些部分组成 文字、图片、…