[C语言]-字符串函数与内存操作函数介绍

目录

1.求字符串长度

1.1 strlen函数 

1.2 模拟实现strlen函数

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

2.1.1 strcpy函数

2.1.2模拟实现strcpy函数

2.2.1 strcat函数

2.2.2模拟实现strcat函数

2.3.1 strcmp函数

2.3.2模拟实现strcmp函数

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

3.1.1 strncpy函数

3.1.2 模拟实现strncpy函数

3.2.1 strncmp函数

3.2.2 模拟实现strncmp函数

3.3.1 strncat函数

3.3.2模拟实现strncat函数

4.字符串查找

4.1.1 strstr函数

4.1.2模拟实现strsr函数

4.2.1 strtok函数

5.错误信息报告

strerror函数

6.内存操作函数

6.1.1 memcpy函数

6.1.2模拟实现memcpy函数

6.2.1 memmove函数

6.2.2模拟实现memmove函数

6.3memcmp函数

6.4 memset函数


1.求字符串长度

1.1 strlen函数 

size_t strlen ( const char * str );

作用:从起始位置以‘\0’作为结束标志,返回‘\0’前的字符个数。

参数:一个char* 类型的指针,

返回类型:size_t    无符号的

注意事项:指针指向的字符串必须是以‘\0’结尾的。

1.2 模拟实现strlen函数

size_t my_strlen(const char* arr)
{
	assert(arr);
	int count = 0;
	while (*arr != '\0')
	{
		count++;
		arr++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdefg";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

assert() 用于断言,判断传入是否为空指针,是则报错。

使用时需要包含头文件include<assert.h>

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

2.1.1 strcpy函数

char* strcpy(char * destination, const char * source );

作用:将源字符串内容拷贝到指定字符串中。

参数:两个char*的指针。

返回类型:char*  为了实现链式访问

注意事项:

① 源字符串需以‘\0’结束。

② strcpy函数会将源字符串的‘\0’一起拷入到目标空间

③ 目标空间必须足够大且可变,以确保能存放源字符串。

2.1.2模拟实现strcpy函数

char* my_strcpy(char* arr1, const char* arr2)
{
	assert(arr1);
	assert(arr2);
	char* str = arr1;
	while ((*arr1++ = *arr2++))
	{
		;
	}
	return str;
}
int main()
{
	char arr1[20] = "helloworld";
	char arr2[] = "****";
	printf("%s\n", my_strcpy(arr1, arr2));
	return 0;
}

2.2.1 strcat函数

char * strcat ( char * destination, const char * source );

作用:将源字符串追加到指定字符串后。

参数:两个char*的指针。

返回类型:char* 

注意事项:

① 源字符串需以‘\0’结束。

②从源字符串的‘\0’位置开始追加。

③ 目标空间必须足够大且修改,以存放源字符串内容。

④  不能自己给自己追加。

2.2.2模拟实现strcat函数

char* my_strcat(char* arr1,const char* arr2)
{
	assert(arr1);
	assert(arr2);
	char* str = arr1;
	while (*arr1 != '\0')
	{
		arr1++;
	}
	while (*arr1++ = *arr2++)
	{
		;
	}
	return str;
}
int main()
{
	char arr1[20] = "hello";
	char arr2[] = "world";
	printf("%s\n",my_strcat(arr1, arr2));
	return 0;
}

2.3.1 strcmp函数

int strcmp ( const char * str1, const char * str2 );

作用:比较两个字符串它对应位置上字符的大小,而非长度。

参数:两个char*的指针。

返回类型:int 

注意事项:

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

2.3.2模拟实现strcmp函数

int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1);
	assert(arr2);
	while (*arr1 == *arr2)
	{
		if (*arr1 == '\0' || *arr2 == '\0')
			return 0;
		arr1++;
		arr2++;
	}
	if (*arr1 > *arr2)
	{
		return 1;
	}
	else
		return -1;
}

int main()
{
	char arr1[] = "abdef";
	char arr2[] = "abd";
	int ret = my_strcmp(arr1, arr2);
	if (ret == 0)
		printf("相等\n");
	else if (ret == 1)
		printf("大于\n");
	else
		printf("小于\n");
	return 0;
}

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

3.1.1 strncpy函数

char * strncpy ( char * destination, const char * source, size_t num );

作用:从源字符串拷贝num个字符到目标空间。

参数:两个char*的指针;一个无符号类型的num,表示要拷贝的字节数

返回类型:char*

注意事项:

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

3.1.2 模拟实现strncpy函数

char* my_strncpy(char* arr1, const char* arr2, size_t num)
{
	assert(arr1);
	assert(arr2);
	char* str = arr1;
	while (num && (*arr1++ = *arr2++) != '\0')
	{
		num--;
	}
	if (num != 0)
	{
		*arr1 = '\0';
		num--;
	}
	return str;
}

int main()
{
	char arr1[] = "hello world";
	char arr2[] = "####";
	printf("%s\n",my_strncpy(arr1, arr2, 4));
	return 0;
}

3.2.1 strncmp函数

int strncmp(const char * destination, const char * source, size_t num );

作用:比较两个字符串它对应位置上字符的大小,比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

参数:两个char*的指针;一个无符号类型的num,表示要比较的字节数

返回类型:int 

注意事项:

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

3.2.2 模拟实现strncmp函数

int my_strcmp(const char* arr1, const char* arr2,size_t num)
{
	assert(arr1);
	assert(arr2);
	while (num && (*arr1 != '\0' || *arr2 != '\0'))
	{
		if (*arr1 == *arr2)
		{
			arr1++;
			arr2++;
			num--;
		}
		else if (*arr1 > *arr2)
			return 1;
		else
			return -1;
	}
	return 0;
}

int main()
{
	char arr1[] = "abdef";
	char arr2[] = "abdeq";
	int ret = my_strcmp(arr1, arr2,5);
	if (ret == 0)
		printf("相等\n");
	else if (ret == 1)
		printf("大于\n");
	else
		printf("小于\n");
	return 0;
}

3.3.1 strncat函数

char * strncat ( char * destination, const char * source, size_t num );

作用:将源字符串num个字节内容追加到指定字符串后。

参数:两个char*的指针;一个无符号类型的num

返回类型:char* 

注意事项:可以自己给自己追加。

3.3.2模拟实现strncat函数

char* my_strcat(char* arr1,const char* arr2,size_t num)
{
	assert(arr1);
	assert(arr2);
	char* str = arr1;
	while (*arr1 != '\0')
	{
		arr1++;
	}
	while (num && (*arr1++ = *arr2++)!='\0')
	{
		num--;
	}
	return str;
}
int main()
{
	char arr1[20] = "hello";
	char arr2[] = "world";
	printf("%s\n", my_strcat(arr1, arr2,3));
	return 0;
}

4.字符串查找

4.1.1 strstr函数

char * strstr ( const char *str1, const char * str2);

作用:在目标字符串中查找源字符串是否存在。

参数:两个char*的指针。

返回类型:char* 

存在:返回子串第一次出现的位置

不存在:返回 NULL

4.1.2模拟实现strsr函数

char* my_strstr(const char* arr1, const char* arr2)
{
	const char* s1 = arr1;
	const char* s2 = arr2;
	const char* p = arr1;

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

	while (*p)
	{
		s1 = p;
		s2 = arr2;
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return p;
		p++;
	}
	return NULL;
}
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "abc";
	char* ret = my_strstr(arr1, arr2);
	if(ret==NULL)
		printf("不存在\n");
	else
		printf("%s\n", ret);
	return 0;
}

4.2.1 strtok函数

char * strtok ( char * str, const char * sep );

作用:strtok函数找到str中的下一个标记,并将其用\0 结尾,返回一个指向这个标记的指针。即找到第一个分割符,用\0替换它,返回起始位置的地址

参数:sep参数是个字符串,定义了用作分隔符的字符集合

第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 

返回类型:char* 

注意事项:

① strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容。

② strtok 函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串中的位置。
③  strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。

5.错误信息报告

strerror函数

char * strerror ( int errnum );

功能:返回错误码,所对应的错误信息。

注意:头文件是<errno.h>

6.内存操作函数

6.1.1 memcpy函数

void * memcpy ( void * destination, const void * source, size_t num );

作用:source的位置开始向后复制num个字节的数据到destination的内存位置。

参数:两个void*的指针;一个无符号类型的num

返回类型:void*

注意事项:

① 这个函数在遇到 '\0' 的时候并不会停下来。
② 如果 source destination 有任何的重叠,复制的结果都是未定义的。

6.1.2模拟实现memcpy函数

void* my_memcpy(void* str1, const void* str2, size_t num)
{
	void* str = str1;
	while (num)
	{
		*((char*)str1)++ = *((char*)str2)++;
		num--;
	}
	return str;
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	my_memcpy(arr1, arr2, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

6.2.1 memmove函数

void * memmove ( void * destination, const void * source, size_t num );

与memcpy函数相同

区别:memmove函数处理的源内存块和目标内存块是可以重叠的

6.2.2模拟实现memmove函数

void* my_memmove(void* dest, void* src, size_t num)
{
	void* str = dest;
	if (dest < src)
	{
		while (num)
		{
			*((char*)dest)++ = *((char*)src)++;
			num--;
		}
	}
	else
	{
		while (num)
		{
			*((char*)dest+num) = *((char*)src+num);
			num--;
		}
	}
	return str;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr + 1, arr, 10);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

6.3memcmp函数

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
作用:比较从 ptr1 ptr2 指针开始的 num 个字节
返回值:
>0
=0
<0

6.4 memset函数

void * memset ( void * destination, int c,size_t num );
作用:以字节单位修改内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值