字符函数和字符串函数

求字符串长度

strlen

功能:求字符串长度
在这里插入图片描述

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

strlen函数的使用

#include <stdio.h>
#include <string.h>  //strlen对应头文件
int main()
{
	char arr[] = "abcdef";
	int len = strlen(arr);
	printf("%d\n", len);
	return 0;

在这里插入图片描述

strlen 的模拟实现

1.创建临时变量count
#include <stdio.h>
size_t my_strlen(char* p)
{
	int count = 0;
	while (*p++)
	{
		count++;
	}
	return count;
}
2.指针相减
#include <stdio.h>
size_t my_strlen(char* p)
{
	char* pp = p;
	while (*p)
		p++;
	return p - pp;
}
3.递归
size_t my_strlen(char* p)
{
	if (*p == '\0')
		return 0;
	return  1 + my_strlen(p + 1);
}
int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%d", ret);
	return 0;
}

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

strcpy

功能:字符串拷贝,把一个字符串里面的内容拷贝到另一个字符串中去(包括’\0’)。
在这里插入图片描述

源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。

strcpy函数的使用

#include <stdio.h>
#include <string.h>  //strcpy对应头文件
int main()
{
	char arr1[] = "abcdef";
	char arr2[10] = { 0 };
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述

strcpy的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);//判断指针是否为空指针
	char* p = dest;//标记起始位置
	while (* dest++ = * src++)
		;
	return p;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };//确保空间足够大
	//strcpy(arr2, arr1);
	char* ret = my_strcpy(arr2,arr1);
	printf("%s", ret);
	return 0;
}

strcat

功能:字符串追加,在一个字符串的末尾追加另外一个字符串(包括’\0’)。
在这里插入图片描述

源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改

strcat函数的使用

#include <stdio.h>
#include <string.h>  //strcat对应头文件
int main()
{
	char arr1[] = "world!";
	char arr2[20] = "hello ";
	strcat(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述

strcat的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);//判断指针是否为空指针
	char* p = dest;
	while (*dest)
		dest++;
	while (*dest++ = *src++)
		;
	return p;
}
int main()
{
	char arr1[] = "abcd";
	char arr2[10] = { 'n'};
	//strcat(arr2, arr1);
	char* ret = my_strcat(arr2, arr1);
	printf("%s", ret);
	return 0;
}

strcmp

功能:字符串比较,比较两个字符串的大小
在这里插入图片描述

第一个字符串大于第二个字符串,则返回大于0的数字。
第一个字符串等于第二个字符串,则返回0。
第一个字符串小于第二个字符串,则返回小于0的数字。

strcmp函数的使用

#include <stdio.h>
#include <string.h>  //strcmp对应头文件
int main()
{
	char str1[] = "abcdef";
	char str2[] = "abq";
	int ret = strcmp(str1, str2);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

strcmp的模拟实现

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* p1, const char* p2)
{
	assert(dest && src);//判断指针是否为空指针
	while (*p1 == *p2)
	{
		if (*p1 == '\0')
			return 0;
		p1++;
		p2++;
	}
	return *p1 - *p2;
}
int main()
{
	char arr1[] = "abcde";
	char arr2[] = "abd";
	//int ret = strcmp(arr1, arr2);
	int ret = my_strcmp(arr1,arr2);
	printf("%d", ret);
	return 0;
}

长度受限制的字符串函数介绍

strncpy

功能:字符串拷贝,把一个字符串中num个字节的内容拷贝到另一个字符串中去。
在这里插入图片描述

拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

strncpy函数的使用

#include <stdio.h>
#include <string.h>  //strncpy对应的头文件
int main()
{
	char arr1[] = "abcdef";
	char arr2[10] = { 0 };
	strncpy(arr2, arr1, 6);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述

strncat

功能:字符串追加,将一个字符串中num个字节的内容追加到另一个字符串的末尾,并在最后面加上’\0’。
在这里插入图片描述
strncat函数的使用

#include <stdio.h>
#include <string.h>  //strncat对应的头文件
int main()
{
	char arr1[] = "world!";
	char arr2[20] = "hello ";
	strncat(arr2, arr1, 6);
	printf("%s\n", arr2);
	return 0;
}

在这里插入图片描述

strncmp

功能:字符串比较,比较两个字符串中前num个字节的大小。
在这里插入图片描述
strncmp函数的使用

#include <stdio.h>
#include <string.h>  //strncmp对应的头文件
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcq";
	int len = strncmp(arr2, arr1, 4);
	printf("%d\n", len);
	return 0;
}

在这里插入图片描述

字符串查找

strstr

功能:查找子串,查找一个字符串中是否包含子串。
在这里插入图片描述
strstr函数的使用

#include <stdio.h>
#include <string.h>  //strstr对应头文件
int main()
{
	char arr1[] = "aabcdef";
	char arr2[] = "abcd";
	char* ret = strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

在这里插入图片描述

strstr的模拟实现

#include <stdio.h>
char* my_strstr(const char* p1, const char* p2)
{
	char* p = p1;
	char* s1 = p1;
	char* s2 = p2;
 	while (*p)
	{
		s1 = p;
		s2 = p2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return p;
		p++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "aabcdef";
	char arr2[] = "abc";
	//char* ret = strstr(arr1, arr2);
	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s", ret);
	else
		printf("不存在");
	return 0;
}

strtok

功能:字符串分割,把一个字符串按照分割标志分割为几个字符串。
在这里插入图片描述

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

strstr函数的使用

#include <stdio.h>
#include <string.h>
int main()
{
	char* sep = "@.";
	char email[] = "01234567@qq.com";
	char tmp[20] = { 0 };
	//由于strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都会临时拷贝一份,操作拷贝的数据
	strcpy(tmp, email);
	printf("%s\n", strtok(tmp, sep));  //第一次第一个参数传递被切割字符串的首地址
	printf("%s\n", strtok(NULL, sep));   //第二次及以后第一个参数传递空指针(strtok会记住上一次切割的位置)
	printf("%s\n", strtok(NULL, sep));
	return 0;
}

错误信息报告

strerror

功能:C语言有一系列的库函数,当这些库函数调用失败时,会返回相应的错误码,而strerror函数的作用就是获取错误码对应的错误信息的首地址,让使用者知道程序发生错误的原因。
在这里插入图片描述
strerror函数的使用

#include <stdio.h>  
#include <string.h>  //strerror的头文件
int main()
{
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	printf("%s\n", strerror(5));
	return 0;
}

在这里插入图片描述

内存操作函数

memcpy

功能:内存拷贝,将一块内存中num个字节的内容拷贝到另一块内存中,常用来处理不重叠内存数据的拷贝。
在这里插入图片描述

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

memcpy函数的使用

#include <stdio.h>
#include <string.h>   //memcpy对应头文件
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[10] = { 0 };
	memcpy(arr2, arr1, 20);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

在这里插入图片描述

memcpy的模拟实现

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

int main()
{
	//char arr1[] = "abcdef";
	//char arr2[20] = { 0 };
	int arr1[] = { 1,2,3,44,5 };
	int arr2[20] = { 0 };
	//memcpy(arr2, arr1, 6);
	my_memcpy((char*)arr2, (char*)arr1, 16);
	//printf("%s", arr2);
	for (int i = 0; i < 4; i++)
		printf("%d ", arr2[i]);
	return 0;
}

memmove

功能:内存移动,将一块内存数据中的内容移动覆盖至另一块内存数据,常用来处理重叠内存数据的拷贝。
在这里插入图片描述

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。

memmove函数的使用

#include <stdio.h>
#include <string.h>  //memmove对应头文件
int main()
{
	int arr1[] = { 1,2,3,4,5,6 ,7,8 };
	int arr2[10] = { 0 };
	memmove(arr1 + 2, arr1,16);
	for (int i = 0; i < 8; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

在这里插入图片描述

memmove的模拟实现

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

int main()
{
	char arr1[20] = "abcdefghij";
	//               ababcghij
	//               cdedefghij
	//int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//               1 2 1 2 3 6 7 8 9 10
	//char arr2[] = "abcd";
	//memmove(arr1 + 2, arr1, 2);
	 my_memmove(arr1 + 2, arr1, 12);
	printf("%s", arr1);
	/* for (int i = 0; i < 10; i++)
		 printf("%d ", arr1[i]);*/
	return 0;
}

memcmp

功能:内存比较,比较两块内存中前num个字节的大小。

在这里插入图片描述

比较从ptr1和ptr2指针开始的num个字节
在这里插入图片描述

memcmp函数的使用

#include <stdio.h>
#include <string.h>  //memcmp对应头文件
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3 };
	int ret = memcmp(arr1, arr2, 12);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

memcmp的模拟实现

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

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	assert(ptr2 && ptr2);
	size_t count = 0;  
	while (*(char*)ptr1 == *(char*)ptr2 && count < num)  
	{ 
		ptr1 = (char*)ptr1 + 1;
		ptr2 = (char*)ptr2 + 1;
		count++; 
	}
	if (count < num)  
		return *(char*)ptr1 - *(char*)ptr2;  
	else
		return 0;  
}

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3 };
	int ret = my_memcmp(arr1, arr2, 12);
	printf("%d\n", ret);
	return 0;
}

memset

功能:内存设置,把一块内存中num个字节的内容设置为指定的数据。
在这里插入图片描述
memset函数的使用

#include <stdio.h>
#include <string.h>  //memset对应头文件
int main()
{
	char str[] = "hello world";
	memset(str, '0', 5);
	printf("%s\n", str);
	return 0;
}

在这里插入图片描述

memset的模拟实现

#include <stdio.h>
#include <assert.h>
void* my_memset(void* dest, int a, size_t num)
{
	assert(dest != NULL);
	void* ret = dest;  
	while (num--)  
	{
		*(char*)dest = a;
		dest = (char*)dest + 1;
	}
	return ret;
}

int main()
{
	char str[] = "hello world";
	my_memset(str, 'x', 5);
	printf("%s\n", str);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值