字符串函数的模拟实现

字符串函数的模拟实现

  1. strcpy的模拟实现

我们知道strcpy的功能是将源指向的C字符串复制到目标指向的数组中,包括终止数组

空字符(并在该点停止)。

需要注意的是:

  • 源字符串必须以 ‘\0’ 结束
  • 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变
    仿照库函数strcpy的标准来实现同样功能的一个函数my_strcpy,源字符串中的’\0’会覆盖掉目标字符串剩下的字符串。
    代码如下:
char* my_strcpy(char *dest, const char *src)
{
	char *ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while ((*dest++ = *src++))
	{  ; }
	return ret;
}

int main()
{
	char arr[100] = { 0 };
	char brr[] = "world";
	char* ret = my_strcpy(arr, brr);
	printf("%s\n", ret);
	return 0;
}
  1. strcmp的模拟实现

strcmp的功能为:比较每个字符串的第一个字符。如果它们彼此相等,则继续执行以下对操作,直到字符不同或到达终止的空字符为止。

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

那么如何比较两个字符串?

逐个比较两个串中对应的字符,字符大小按照ASCII码值确定,从左向右比较,如果遇到不同字符,所遇第一对不同字符的大小关系就确定了两个字符串的大小关系,如果未遇到不同字符而某个字符串首先结束,那么这个字符串是较小的,否则两个字符串相等。

在写这个代码的时候,要注意写while的循环条件*str1==*str2时,用括号括上,以符号在编译时由于编译器分辨不清优先级而结果错误;在打印时注意输出形式的对应,记准%s、%d、%c等c语言的格式输出。

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1!=NULL);
	assert(str2!=NULL);
	while ((*str1 == *str2))
	{
		if (*str1 == '0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcq";
	printf("%d\n", my_strcmp(arr1,arr2));

	return 0;
}
  1. strstr的模拟实现

strstr的功能为:返回指向str1中第一次出现的str2的指针,如果str2不是str1的一部分,则返回空指针。
在写这个函数时要考虑多种情况,不能只考虑简单的情况,比如,arr1[]=“abbbcde”,arr2[]="bbc"这种稍微复杂一点的情况,设置三个指针分别指向str1,str2,cur负责记录s1与s2比较的起始位置。
在这里插入图片描述
当s1不等于s2时,s1向后走,同时,cur也向后移动一个位置。
在这里插入图片描述
此时,s1=s2,s1继续向后走,s2同样继续向后走,此时s1=b=s2=b,重复上述过程,s1继续往后走,s2也继续往后走,此时,s1=b,s2=c,s1与s2不再匹配在这里插入图片描述
此时,cur向后走,s1返回cur的位置,s2返回最开始的位置,s1与s2重新比较,在这里插入图片描述
重复上述过程,s1向后走,s2向后走,当s1=s2=c时,s2已访问完,此时,已在s1中找到与s2完全相同的字符串,这时应返回cur的的位置,并打印该字符串。
在这里插入图片描述
此外,也可能遇见s2还没访问完,s1已经结束,比如,arr1[]=“abcdef”,arr2[]=“defg”,此时,str1中并未找到与str2相符的字符串,故应返回空指针。
具体代码如下:

char *my_strstr(char *str1, const char *str2)
{
	char* s1 = str1;
	char* s2 = str2;
	char* cur = str1;
	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cur;
		}
		/*if (*s1 == '0')
		{
			return NULL;
		}*/
		cur++;
	}
	return NULL;
}
int main()
{
	char arr[] = "abcdef";
	char brr[] = "bc";
	char *ret = my_strstr(arr, brr);
	printf("%s\n", ret);
	return 0;
}

4.strcat

char *my_strcat(char *dest, const char *src)
{
	char *ret = dest;
	assert(dest != NULL);
	assert(src != NULL);

	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[] = {0};
	char arr2[] = "world";
	char *ret = my_strcat(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

5.strchr的模拟实现
strchr的功能:找出某个字符在字符串中第一次出现的地址,相对于strstr比较简单,具体代码如下:

char *MyStrchr(const char *dest, const char c)
{
	assert(dest);

	while (*dest)
	{
		if (*dest == c)
		{
			return dest;
		}
		dest++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abcdef";
	char *ret = strchr(arr1,'d' );
	printf("%s\n", ret);
}

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

具体代码如下:

void * memcpy(void * dst, const void * src, size_t count)
{
	void * ret = dst;
	/* copy from lower addresses to higher addresses*/
	while (count--)
	{
		*(char *)dst = *(char *)src;
		dst = (char *)dst + 1;
		src = (char *)src + 1;
	}
	return (ret);
}
int main()
{
	char arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, };
	char arr2[] = { 1, 2 };
	my_memcpy(arr1, arr2, strlen(arr1));
	printf("%s", arr1);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41181857/article/details/86167729
今日推荐