字符串函数与内存函数的介绍运用和模拟实现

在C语言中函数的学习也是一个很重要的知识板块,下文将为读者介绍一下如何运用一些字符串函数和内存函数

字符串函数

1 求字符串长度的函数:strlen
2 复制字符串的函数: strcpy , strncpy
3 追加字符串的函数: strcat , strncat
4 比较字符串的函数: strcmp , strncmp
5 查找子串的函数: strstr
6 截断字符串的函数: strtok
7 报告错误信息的函数: strerror

内存函数

1 不同内存块之间的复制函数:memcpy
2 内存块出现重叠的复制函数:memmove
3 给内存块的赋值函数: memset
4 内存块之间的比较函数:memcmp

求字符串长度的函数:strlen
该函数原型可以从msdn中查找到:size_t strlen( const char *string ),所对应的头文件是string.h
size_t代表了返回一个无符号整形,传入的是要查询长度的字符串的首地址,要注意到,字符串是以‘ \0 ’结尾的,所以这个函数的原理就是从起始地址开始检查,一旦遇到‘\0’结束,并记录‘\0’之前的字符个数。
最后返回一个无符号整形,即字符个数。
所以我们可以根据这样来复现这个函数
第一种是计数器的方式来实现
在这里插入图片描述
第二种是不创建临时变量,采用递归的方式来实现

在这里插入图片描述
第三种是用指针减去指针的方式去实现
在这里插入图片描述
复制字符串的函数: strcpy , strncpy
这两个函数第一个是复制的长度无限制,第二个是复制的长度有限制,在MSDN中的函数原型分别是
strcpy: char *strcpy( char *strDestination, const char *strSource );
strncpy: char *strncpy( char *strDest, const char *strSource, size_t count );
我们可以看到第二个函数只是多了一个要复制字符串长度的量
而对于这两个函数的模拟实现,第一个就是一直复制到’\0’,而第二个就根据给定的长度来复制
这两个函数最后都是返回目标字符串的地址

strcpy:
在这里插入图片描述

strncpy:
在这里插入图片描述
追加字符串的函数: strcat , strncat
同上两个函数一样,只是后一个多了长度的限制
在MSDN中两函数原型是
strcat: char *strcat( char *strDestination, const char *strSource );
strncat:char *strncat( char *strDest, const char *strSource, size_t count );
最后会返回目标字符串的地址

strcat:
在这里插入图片描述
strncat:
在这里插入图片描述
比较字符串的函数: strcmp , strncmp
二者函数在MSDN中的函数原型分别是
strcmp: int strcmp( const char *string1, const char *string2 );
strncmp: int strncmp( const char string1, const char string2, size_t count );
strcmp是一个比较有趣的函数,因为它的机理是逐个比较字符的大小,如果
string1小于
string2,那么它将返回一个小于0的数字,如果大于那么返回一个大于0的数字,如果这两个字符相等,则继续往下比,如果比到最后也相同则返回0。其实也就是只要遇到不同的字符,这个函数也就结束了。
strcmp:

在这里插入图片描述
strncmp:
在这里插入图片描述
查找子串的函数: strstr
strstr在MSDN中的函数原型:char *strstr( const char *string, const char *strCharSet );
这个函数有三种返回值,如果strCharSet 不在string中,返回空指针
如果strCharSet 为空指针,返回string的地址
如果strCharSet 在string中,返回strCharSet 在string中对应的地址
如下图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
strstr:
在这里插入图片描述

下面附上代码

char*my_strstr(const char *string, const char *strcheck)
{
	assert(*string);
	const char * p1 = string;
	if (*strcheck == '\0')
	{
		return (char*)string;
	}
	while (*p1)
	{
		const char * p2 = strcheck;
		const char *p3 = p1;
		while (*p3 !='\0'&& *p3 == *p2 && *p2 !='\0')
		{
			p3++;
			p2++;
		}
		if (*p2 == '\0')
		{
			return (char *)p1;
		}
		p1++;	
	}
	return NULL;
	
}
int main()
{
	char arr1[] = "abcdefghijk";
	char arr2[] = "bcd";
	if (my_strstr(arr1, arr2) == NULL)
	{
		printf("No\n");
	}
	else if (my_strstr(arr1, arr2) == arr1)
	{
		printf("arr2 is empty arrary\n");
	}
	else
	{
		printf("%p\n", my_strstr(arr1, arr2));
		printf("%p\n", arr1);
		printf("%p\n", arr2);
	}
}

** 截断字符串的函数: strtok**
该函数在MSDN中的函数原型是:char *strtok( char *strToken, const char *strDelimit )
第一个地址是要剪切的字符串的地址,第二个字符串是用作分隔符的字符的集合
第一个参数指定的字符串,它包含了0个或者多个由strDelimit 字符串中一个或者多个分隔符分割的标记。
strtok函数找到strToken中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。下面有两个例子
在这里插入图片描述
在这里插入图片描述

报告错误信息的函数: strerror
strerror在MSDN中的函数原型是:char *strerror( int errnum );
errnum是错误代码对应的数字,根据不同的数字,返回不同错误解释的地址
下面给出一个例子
在这里插入图片描述

不同内存块之间的复制函数:memcpy
memcpy在MSDN中的函数原型是:void *memcpy( void *dest, const void *src, size_t count );
第一个是目标地址,第二个是源地址,第三个是复制的字节数
最后则会返回目标地址
要注意C语言中只规定memcpy的作用是在不同内存块之中起作用就可以,有些编译器在有重叠的内存块中也能实现
所以下图中模拟实现中,是在arr1和arr2之间进行拷贝
memcpy:
在这里插入图片描述
内存块出现重叠的复制函数:memmove
memmove在MSDN中的原函数是:void *memmove( void *dest, const void *src, size_t count );
参数意义和memcpy差不多,只是memmove是在内存块可以重叠的区域中也满足
在这里插入图片描述
下面附上代码

void print(int *arr, size_t i)
{
	size_t j = 0;
	for (; j < i; j++)
	{
		printf("%d ",arr[j]);
	}
}
void * my_memmove(void *dest, const void * src, size_t count)
{
	void *p1 = dest;
	if (src < dest)//源地址小于目标地址需要从后到前进行拷贝,否则会出现重复覆盖的情况,致使拷贝失败
	{
		while (count--)
		{
			*((char *)dest + count) = *((char *)src + count);
		}
		return p1;
	}
	
	else //否则就从前到后进行拷贝
	{
		while (count--)
		{
			*(char *)dest = *(char *)src;
			((char *)dest)++;
			((char *)src)++;
		}
		return p1;
	}
}
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	my_memmove(arr + 3, arr, 20);
	print(arr,10);
}

给内存块的赋值函数: memset

memset在MSDN中的函数原型是:void *memset( void *dest, int c, size_t count );
第一个参数是目标内存的地址,第二个是要设置的字符对应的ASCII码值,第三个是要设置的个数
最后返回目标内存地址
下面举个栗子(第二张是一张不全的ASCII码表)在这里插入图片描述在这里插入图片描述

内存块之间的比较函数:memcmp
memcmp在MSDN中的函数原型是:int memcmp( const void *buf1, const void *buf2, size_t count );
第一个和第二个参数分别是两个内存地址,然后从两个地址开始比较count个字节。
原理和strcmp差不多
下面举个栗子,由于G的ASCII码值是小于g的ASCII码值,所以当比较到第三个字节的时候,就出现结果了
在这里插入图片描述
看到这,希望这篇文章对你有所帮助,感谢观看!一起加油吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值