字符串函数+内存函数(详解)

这篇具有很好参考价值的文章主要介绍了字符串函数+内存函数(详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.引言

本期带大家一起来学习字符串函数+内存函数😀 😃 😄

一、字符串函数📌📌

1. 求字符串长度 strlen🚀🚀

字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。

#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";
	size_t len = strlen(p);
	printf("len=%zd\n", len);
	return 0;
}

字符串函数+内存函数(详解)
strlen在库里面的参数是如此的⌛️⌛️
接下来我们来模拟实现strlen,接下来使用三种方法求字符串长度

//方法一     使用循环求字符串长度
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* p)
{
	assert(p);
	size_t len = 0;
	while (*p != '\0')
	{
		p++;
		len++;
	}
	return len;
}
int main()
{
	char* p = "abcdef";
	size_t len = my_strlen(p);
	printf("len=%zd\n", len);
	return 0;
}


//方法二         递归求字符串长度
#include<stdio.h>
#include<assert.h>
unsigned int mystrlen(const char* p)
{
	assert(p);
	if (*p == '\0')
		return 0;
	return 1 + mystrlen(p + 1);
}
int main()
{
	char arr[] = "abcdefghi";
	unsigned int ret = mystrlen(arr);
	printf("%u", ret);
	return 0;
}


//方法三       运用指针求字符串长度
#include<stdio.h>
#include<assert.h>
unsigned int mystrlen(const char* p)
{
	assert(p);
	char* start = p;
	while (*p != '\0')
	{
		p++;
	}
	return p - start;

}
int main()
{
	char arr[] = "abcdefghi";
	unsigned int ret = mystrlen(arr);
	printf("%u", ret);
	return 0;
}

注意点:
字符串是以’\0’作为结束的标志,strlen是统计字符串’\0’之前的字符。
参数指向的字符串必须要以 ‘\0’ 结束
字符串的返回类型是size_t类型。

2.长度不受限制的字符串函数🚀🚀

2.1 strcpy🌴🌴

字符串函数+内存函数(详解)
strcpy在库里面的参数是如此的
接下来我们来模拟实现strcpy

#include<stdio.h>
#include<assert.h>
char* mystrcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	while (*dest++ = *src++)
	{
		;
	}
	return ret;

}
int main()
{
	char arr[20] = "abcdef";
	char str[20] = "hello world";
	char *ret=mystrcpy(arr, str);
	printf("%s\n", ret);
	return 0;
}

strcpy函数注意点:⌛️⌛️
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。🔑🔑

2.2 strcat🌴🌴

字符串函数+内存函数(详解)

strcat是字符串追加函数,能够将源字符串的字符追加到目标字符串中。
💬💬 strcpy函数注意点:🔑🔑🔑
返回类型是char*(返回的是目标字符串首的地址)
接下来模拟实现strcat

#include<stdio.h>
#include<assert.h>
char* mystrcat(char* dest, const char* src)
{
 assert(dest&&src);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr[20] = "hello ";
	char* p = "abcdef";
	char str[20] = "world";
	char* ret = mystrcat(arr, str);
	printf("%s\n", ret);
	return 0;
}

注意点:strcat函数💬💬
源字符串 必须以’\0’ 结束
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
不能自己给自己追加字符串,程序会崩溃❗️❗️❗️

📣📣当我们自己给自己追加的时候,会出现死循环,接下来看图解📣📣
字符串函数+内存函数(详解)

2.3 strcmp🌴🌴

字符串函数+内存函数(详解)

strcmp是字符串比较函数,该函数是从二个字符串的元素开始🚩🚩
进行比较 (比较本质为字母ascii码值的大小)
接下来模拟实现strcmp

#include<stdio.h>
#include<assert.h>
int mystrcmp(const char* p,const char * q)
{
	assert(p && q);
	while (*p == *q)
	{
		p++;
		q++;
		if (p == '\0')
			return 0;
	}
	return *p - *q;
}
int main()
{
	char* p = "abcdef";
	char* q = "abcccc";
	int ret = mystrcmp(p, q);
	printf("%d\n", ret);
	return 0;
}

标准规定: strcmp函数
第一个字符串大于第二个字符串, 则返回大于0的数字🌈
第一个字符串等于第二个字符串,则返回0🌈🌈
第一个字符串小于第二个字符串,则则返回小于0的数字🌈🌈🌈

3.长度受限制的字符串函数🍎🍎

上面的 strcmp,strcpy,strcat都是长度不限制字符串函数,具有一定的风险性,这和VS当中scanf函数一样,具有一定的风险,所以下面来介绍长度受限制的字符串函数 strncmp,strncpy,strncat

3.1 strncpy⚓️⚓️

字符串函数+内存函数(详解)

这是strncpy的参数,前两个参数和 strcpy是一样的,不同的是第三个参数
第三个参数则是传入需要复制的 字符 个数
字符串函数+内存函数(详解)

3.2 strncat⚓️⚓️

字符串函数+内存函数(详解)

这是strncat的参数,前两个参数和 strcat是一样的,不同的是第三个参数
第三个参数则是传入需要连接第二个参数 src 字符 个数
字符串函数+内存函数(详解)
当我们的传入的 第三个参数小于字符串长度
后面会自动补 斜杠0
字符串函数+内存函数(详解)

3.3 strncmp⚓️⚓️

字符串函数+内存函数(详解)

这是strncmp的参数,前两个参数和 strcmpt是一样的,不同的是第三个参数
第三个参数则是传入需要比较的dest 和 src 字符 个数
字符串函数+内存函数(详解)
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
当需要比较的字符个数小于实际的字符串长度
会提前结束
字符串函数+内存函数(详解)

4.字符串查找💡💡

4.1 strstr🌱🌱

字符串函数+内存函数(详解)

这是strstr的参数✔️✔️
返回的是在被查找字符串当中与查找字符串相同的首元素的地址
第一个参数是被查找字符串的首元素的地址
第二个参数是查找字符串的首元素地址
字符串函数+内存函数(详解)

接下来我们来模拟实现strstr
方法一 :暴力求解🌴
方法二 :借助strncmp求解🌴🌴
方法三 :KMP算法求解🌴🌴🌴

//方法一:暴力求解
#include<stdio.h>
#include<assert.h>
char* mystrstr(const char* dest, const char* src)
{
	assert(dest && src);
	char* start = dest;
	while (*start)
	{
		char* p = start;
		char* q = src;
		while (*p == *q && *p && *q )
		{
			p++;
			q++;
		}
		if (*q == '\0')
			return start;
		start++;
	}
	return NULL;
}
int main()
{
	char* p = "abcdededefabc";
	char* q = "def";
	char* ret = mystrstr(p, q);
	printf("%s\n", ret);
	return 0;
}
//方法二:借助strncmp求解
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* mystrstr(const char* dest, const char* src)
{
	assert(dest && src);
	char* p = dest;
	while (*p)
	{
		if (strncmp(p, src, strlen(src)) == 0)
			return p;
		p++;
	}
	return NULL;
}
int main()
{
	char* p = "abcdededefabc";
	char* q = "def";
	char* ret = mystrstr(p, q);
	printf("%s\n", ret);
	return 0;
}

//方法三:KMP算法实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
void my_next(int* next,int n,const char* p)
{
	int j = 0,k=-1;
	next[0] = -1;
	while(j<n)
	{
		if (k == -1 || p[j] == p[k])
		{
			next[j + 1] = k + 1;
			j++;
			k++;
		}
		else
			k = next[k];
	}
}
int KMP(const char* str1, const char* str2)
{
	int i = 0, j = 0;
	int len = (int)strlen(str2);
	//next数组
	int* next = (int*)malloc(len * sizeof(int));
	assert(next);
	my_next(next,len-1,str2);
	while (str2[j])
	{
		if(j==-1||str1[i] == str2[j])
		//j为-1时该位置下的i不会匹配成功,进入下一次匹配
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];//j进行回退
		}
		if (str1[i] == '\0')
		{
			free(next);
			next = NULL;
			return -1;
		}
	}
	free(next);
	next = NULL;
	return i;
}
int main()
{
	char arr[] = "abaabcdabcab";
	char brr[] = "ef";
	printf("%d\n",KMP(arr, brr));
	return 0;
}

4.2 strtok🌱🌱

字符串函数+内存函数(详解)

strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
🔔strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
🔔🔔strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
🔔🔔🔔如果字符串中不存在更多的标记 ,则返回 NULL 指针

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[20] = "abc@dfg#hi.123";
	char* p = "@#.";
	char str[30] = "0";
	strcpy(str, arr);
	char* ret = NULL;
	for (ret = strtok(str, p); ret != NULL; ret = strtok(NULL, p))
	{
		printf("%s\n", ret);
	}
	return 0;
}

字符串函数+内存函数(详解)

5.错误信息报告 strerror🌱🌱

字符串函数+内存函数(详解)

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("Error opening file unexist.ent: %s\n", strerror(errno));
	return 0;
}

🍗🍗 返回错误码,所对应的错误信息🍗🍗
返回的是错误信息

二、内存操作函数📌📌

1.memcpy🚁🚁

字符串函数+内存函数(详解)
函数memcpy从source的位置开始向后
复制num个字节的数据到destination的内存位置。✏️✏️
这个函数在遇到 ‘\0’ 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。
🔑 💡🔑 💡

接下来我们来模拟实现一下memcpy

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

	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int *ret=my_memcpy(arr, arr + 2,5 * sizeof(int));
	int len = sizeof(arr) / sizeof(int);
	while (len--)
	{
		printf("%d ", *ret);
		ret++;
	}
	return 0;
}

🔍🔍my_memcpy的参数是void * ,🔎🔎
void*指针可以接收任何类型的指针,这样子可以接收任何类型的指针,
🔍🔍 并且用将其强制类型转换为char *指针,🔎🔎
每次拷贝一个字节的数据,这样子方便使用并且加强了代码的可执行性

但是我们可以发现,当我们传参到我们的my_memcpy当中,
第一个参数的地址比第二个参数的地址高的时候
会出先重复的情况
❗️❗️❗️接下来看图解❗️❗️❗️
字符串函数+内存函数(详解)
所以接下来我们来学习一下memmove函数,可以解决这个情况

2.memmove🚁🚁

字符串函数+内存函数(详解)

和memcpy的差别就是memmove函数
处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。
接下来我们来模拟实现一下memmove⭐️⭐️⭐️

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

	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr, arr + 2, 5 * sizeof(int));
	my_memmove(arr+2, arr , 5 * sizeof(int));
	char string1[60] = "abcdef123456";
	my_memmove(string1 + 3, string1, 3);
	char string2[60] = "abcdef123456";
	printf("string1=%s\n", string1);

	my_memmove(string2 , string2+3, 3);
	printf("\nstring2=%s\n", string2);
	return 0;
}

3.memset🚁🚁

字符串函数+内存函数(详解)
字符串函数+内存函数(详解)

memset是计算机中C/C++语言初始化函数。
作用是将某一块内存中的内容全部设置为指定的值,
这个函数通常为新申请的内存做初始化工作。
可以注意到第三个参数是需要改变字节的数目
⭐️⭐️⭐️接下来模拟实现memset⭐️⭐️⭐️


#include<stdio.h>
#include<string.h>
void* my_memset(void* dest,int c, size_t count)
{
	while (count--)
	{
		*(char*)dest = (char)c;
		dest = (char*)dest + 1;
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memset(arr, 0,sizeof(int) * 10);
	char str[20] = "abcdef";
	my_memset(str,'a', sizeof(char) * strlen(str));
	printf("%s", str);
	return 0;
}

字符串函数+内存函数(详解)

但是当我们将第二个参数传入1的时候,结果会和我们预想的不一样,这是为什么呢?⁉️⁉️⁉️
因为我们开头提到memset是一个字节一个字节初始化的

1
在内存当中 小端 存储方式如下

01 00 00 00

字符串函数+内存函数(详解)

强制类型转换为char后

是01
字符串函数+内存函数(详解)

所以得出来的结果是⭕️ ⭕️ ⭕️

字符串函数+内存函数(详解)

4.memcmp🚁🚁

字符串函数+内存函数(详解)

字符串函数+内存函数(详解)

memcmp函数和strcmp函数是差不多的🚦
区别在于memcmp函数可以比较任何类型的数据 🚦🚦
而strcmp函数只能比较字符串 🚦🚦🚦

三、感谢与交流📌📌

🌹🌹🌹如果大家通过本篇博客收获了,对字符串函数以及内存操作函数 ,那么希望支持一下哦如果还有不明白的,疑惑的话,或者什么比较好的建议的话,可以发到评论区,
我们一起解决,共同进步 ❗️❗️❗️
最后谢谢大家❗️❗️❗️💯💯💯

字符串函数+内存函数(详解)文章来源地址https://www.toymoban.com/news/detail-416505.html

到了这里,关于字符串函数+内存函数(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】字符函数,字符串函数,内存函数

    大家好!今天我们来学习C语言中的字符函数,字符串函数和内存函数。 目录 1. 字符函数 1.1 字符分类函数 1.2 字符转换函数 1.2.1 tolower(将大写字母转化为小写字母) 1.2.2 toupper(将小写字母转化为大写字母) 2. 字符串函数 2.1 字符串输入函数 2.1.1 gets() ​2.1.2 fgets() 2.2 字符串

    2024年02月10日
    浏览(46)
  • 字符串函数和内存操作函数

    目录 0.字符串回顾 1.函数介绍 1.1 strlen 1.2 strcpy 1.3 strcat 1.4 strcmp 1.5 strncpy 1.6 strncat 1.7 strncmp 1.8 strstr 1.9 strtok 1.10 strerror 1.11 memcpy 1.12 memmove 1.13 memcmp 1.14 memset 1.15 字符相关函数 字符分类函数 字符转换函数 2.函数模拟实现 2.1模拟实现strlen 2.2模拟实现strcpy 2.3模拟实现strcat 2.4模拟

    2024年02月15日
    浏览(97)
  • 字符串和内存函数(2)

    2.13 memcpy void* memcpy(void* destination, const void* source, size_t num); 函数memcpy从source的位置开始向后复制num个 字节 的数据到destination的内存位置。 这个函数在遇到 ‘\\0’ 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。 memcpy是内存拷贝,它可以拷

    2024年02月04日
    浏览(29)
  • <C语言> 字符串内存函数

    C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数. 注意:字符串函数都需要包含头文件string.h strlen() 函数用于计算字符串的长度,即字符串中字符

    2024年02月15日
    浏览(34)
  • 【C】字符串函数和内存函数的介绍

    strlen size_t strlen ( const char * str ); 字符串已经 ‘\\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\\0’ 前面出现的字符个数(不包含 ‘\\0’ )。 参数指向的字符串必须要以 ‘\\0’ 结束。 注意函数的返回值为size_t,是无符号的( 易错 ) 代码演示: 运行结果: strcpy char* s

    2024年02月16日
    浏览(30)
  • c语言——字符串函数和内存操作函数

    包含在string.h头文件里 功能:返回字符串中有效字符的个数,遇到‘\\0’结束,不包括结束符‘\\0’. 函数的参数为------const char* str:字符指针 返回值的类型------size_t:无符号整数(即:unsigned int) 模拟实现strlen: 方法一:计数器的方法 方法二:不能创建临时变量的计数器

    2024年02月14日
    浏览(59)
  • C语言进阶---字符串+内存函数

    重点介绍处理字符和字符串的库函数的使用和注意事项。 求字符串长度 strlen() 长度不受限制的的字符串函数 strcpy() strcat() strcmp() 长度受限制的的字符串函数 strncpy() strncat() strncmp() 字符串查找 strstr() strtok() 错误信息报告 strerror() 字符操作 内存操作函数 memcpy() memmove() memset(

    2024年02月12日
    浏览(43)
  • 【C语言】字符函数与字符串函数以及内存函数 { 超详细攻略,一篇学会 }

    今日分享:字符、字符串函数和内存函数 内存函数 就是对内存进行操作的函数 字符串函数 就是对字符串进行操作的函数 字符函数 就是对字符进行操作的函数 str 前缀的函数是字符串函数,头文件string.h mem 前缀的函数是内存函数,头文件stdlib.h 字符分类函数包含在 ctype.h 头

    2024年03月18日
    浏览(45)
  • 进阶C语言——字符串和内存函数

    今天我们学点库函数 字符函数和字符串函数 求字符串长度函数-strlen strlen需要的头文件是string.h ,那它的作用是什么呢?? 他是来求字符串长度的,统计的是’\\0’前的字符串长度 size_t是无符号的意思 学会了strlen函数怎么使用,那我们现在模拟实现一下strlen 之前讲过三种方

    2024年02月16日
    浏览(35)
  • 【C生万物】 字符串&内存函数篇 (上)

     欢迎来到 Claffic 的博客  💞💞💞                               👉  专栏: 《C生万物 | 先来学C》👈 前言: 过了指针这个坎后,下一步就是C语言中关于字符的处理,这一期来讲讲常用字符函数和字符串函数:strlen,strcpy,strcat,memcpy,memmove,memcmp 等。  目录 Part1:写在前

    2024年02月06日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包