模拟实现字符串函数

一、模拟实现strlen

  • 原型size_t strlen( const char *string );
  • 功能:计算给定字符串的长度(不包括’\0’)
//方法一:计数器方式
int my_strlen(char *s)
{
	int count = 0;
	while (*s)
	{
		count++;
		s++;
	}
	return count;
}

//方法二:递归法,不创建临时变量
int my_strlen(char *s)
{
	if (*s == '\0')
	{
		return 0;
	}
	return (1 + my_strlen(s + 1));
}

//方法三:指针-指针的方式
int my_strlen(char *s)
{
	char *p = s;
	while (*p != '\0')
	{
		p++;
	}
	return p - s;
}
//说明:若两个指针指向同一个数组或同一段内存区域,当两个指针相减时,得到的是这两个指针之间所经历的元素个数,其中元素个数和两个指针变量的类型有关,元素个数=两个指针之间所差总字节数/指针类型所占字节数。

int main()
{
	char s[] = "abcde";
	int len = my_strlen(s);
	printf("%d\n", len);
	system("pause");
	return 0;
}

二、模拟实现strcmp

  • 原型int strcmp( const char *string1, const char *string2 );
  • 功能:用于比较两个字符串的大小,当string1大于string2,返回值为正数;当string1等于string2,返回值为0;当string小于string2,返回值为负数
int my_strcmp(const char *str1, const char *str2)
{
	int ret = 0;
	while (!(ret = *(unsigned char *)str1 - *(unsigned char *)str2) && *str1)
	{
		str1++;
		str2++;
	}
	if (ret < 0)
	{
		ret = -1;
	}
	else if (ret > 0)
	{
		ret = 1;
	}
	return ret;
}

int main()
{
	printf("%d\n", my_strcmp("abc", "abc"));
	printf("%d\n", my_strcmp("abc", "abcd"));
	printf("%d\n", my_strcmp("abcd", "abc"));
	system("pause");
	return 0;
}

三、模拟实现strcpy

  • 原型char *strcpy( char *strDestination, const char *strSource );
  • 功能:把从strSource地址开始且含有结束符的字符串复制到以strDestination开始的地址空间中去,’\0’也复制过去
char *my_strcpy(char *dest, const char *src)
{
	assert(dest != NULL);   //断言
	assert(src != NULL);    //断言
	char *ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char dest[20] = { 0 };
	char src[] = "hello world!";
	printf("%s\n", my_strcpy(dest, src));
	system("pause");
	return 0;
}

四、模拟实现strcat

  • 原型char *strcat( char *strDestination, const char *strSource );
  • 功能:把strSource所指字符串添加到strDestination结尾处(覆盖原’\0’),再添加’\0’
char *my_strcat(char *dest, const char *src)
{
	assert(dest != NULL);
	assert(src != NULL);
	char *ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char dest[10] = "1234";
	char src[] = "abcd";
	printf("%s\n", my_strcat(dest, src));
	system("pause");
	return 0;
}

五、模拟实现strstr

  • 原型char *strstr( const char *string, const char *strCharSet );
  • 功能:用于判断strCharSet所指字符串是否是string所指字符串的子串。如果是,则该函数返回strCharSet在string中首次出现的地址;否则,返回NULL
char *my_strstr(const char *src, const char *dest)
{
	assert(src != NULL);
	assert(dest != NULL);
	char *p_src = (char *)src;
	char *p_dest = (char *)dest;
	char *s = NULL;
	if (*dest == '\0')
	{
		return NULL;
	}
	while (*p_src)
	{
		s = p_src;   //每次在src中查找的起始地址
		p_dest = (char *)dest;
		while (*s && *p_dest && (*s == *p_dest))
		{
			s++;
			p_dest++;
		}
		if (*p_dest == '\0')   //查找成功
		{
			return p_src;
		}
		p_src++;
	}
}

int main()
{
	char dest[] = "abcde";
	char src[] = "abcabcdefg";
	printf("%s\n", my_strstr(src, dest));
	system("pause");
	return 0;
}

六、模拟实现strchr

  • 原型char *strchr( const char *string, int c );
  • 功能:在string所指字符串中找出第一次出现字符c的位置,找到就返回该位置,否则,返回NULL
char *my_strchr(const char *str, char c)
{
	assert(str);
	while (*str++)
	{
		if (*str == c)
		{
			return str;
		}
	}
	return NULL;
}

int main()
{
	char c = 'D';
	char str[] = "ABCDEF";
	printf("%s\n", my_strchr(str, c));
	system("pause");
	return 0;
}

七、模拟实现memcpy

  • 原型void *memcpy( void *dest, const void *src, size_t count );
  • 功能:内存拷贝函数,从src所指的内存地址的起始位置开始拷贝count个字节到目标dest所指的内存地址的起始位置中
void *my_memcpy(void *dest, const void *src, int count)
{
	assert(dest);
	assert(src);
	char *p = (char *)dest;
	const char *q = (const char *)src;
	while (count--)
	{
		*p = *q;
		p++;
		q++;
	}
	return dest;
}

int main()
{
	int src[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int dest[10];
	my_memcpy(dest, src, sizeof(src));
	system("pause");
	return 0;
}

八、模拟实现memmove

  • 原型void *memmove( void *dest, const void *src, size_t count );
  • 功能:用于从src中拷贝count个字节到目标dest中。如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后src内容会被更改;若没有重叠,则和memcpy函数功能相同
    这里写图片描述
void *my_memmove(void *dest, const void *src, int len)
{
	char *ret = dest;
	if (dest > src && (char *)dest < (char *)src + len)   //从右往左拷贝(解决内存区域重叠问题)
	{
		dest = (char *)dest + len - 1;
		src = (char *)src + len - 1;
		while (len--)
		{
			*(char *)dest = *(char *)src;
			dest = (char *)dest - 1;
			src = (char *)src - 1;
		}
	}
	else   //从左往右拷贝
	{
		while (len--)
		{
			*(char *)dest = *(char *)src;
			dest = (char *)dest + 1;
			src = (char *)src + 1;
		}
	}
	return ret;
}

int main()
{
	char str1[10] = "1234abcd";
	char str2[10];
	my_memmove(str1+1, str1, strlen(str1));
	printf("%s\n", str1);
	system("pause");
	return 0;
}
注意:
  1. strcpy:字符串拷贝,只能拷贝字符串
  2. memcpy:内存拷贝,可拷贝任意类型(拷贝时有内存区域重叠问题),按字节为基本单位拷贝
  3. memmove:相对于memcpy,解决了拷贝时内存区域重叠的问题

九、模拟实现strncpy

  • 原型char *strncpy( char *strDest, const char *strSource, size_t count );
  • 功能:把strSource所指字符串中的前count个字节复制到strDest所指字符串中去
  • 说明:如果strSource的前count个字节不含NULL字符,则结果不会以NULL字符结束;如果strSource的长度小于count个字节,则以NULL填充srcDest直到复制完count个字节。strSource和strDest所指内存区域不可以重叠且strDest必须有足够的空间来容纳strSource的字符串。返回值是指向strDest的指针。
char *my_strncpy(char *des, const char *src, int count)
{
	assert(src);
	assert(des);
	char *ret = des;
	while (count && (*des++ = *src++))
	{
		count--;
	}
	if (count>0)
	{
		while (--count)
		{
			*des++ = '\0';
		}
	}
	return ret;
}

int main()
{
	char string[20] = { 0 };
	char arr[] = "hello world";
	printf("String = %s\n", my_strncpy(string, arr, strlen(arr)));
	system("pause");
	return 0;
}

十、模拟实现strncat

  • 原型char *strncat( char *strDest, const char *strSource, size_t count );
  • 功能:把strSource所指字符串的前count个字符添加到strDest结尾处(覆盖strDest结尾处的’\0’),并添加’\0’
  • 说明:strSource和strDest所指内存区域不可以重叠且strDest必须有足够的空间来容纳strSource的字符串;返回值是指向strDest的指针
char *my_strncat(char *dest, const char *src, int count)
{
	assert(src);
	assert(dest);
	char *ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (count-- && (*dest++ = *src++))
	{
		;
	}
	return ret;
}

int main()
{
	char arr[20] = "hello";
	printf("%s\n", my_strncat(arr, arr, strlen(arr)));
	system("pause");
	return 0;
}

十一、模拟实现strncmp

  • 原型int strncmp( const char *string1, const char *string2, size_t count );
  • 功能:比较string1所指字符串和string2所指字符串的前count个字符
  • 说明:当string1大于string2,返回值为正数;当string1等于string2,返回值为0;当string小于string2,返回值为负数
int my_strncmp(const char *str1, const char *str2, int count)
{
	int ret = 0;
	while (count && !(ret = *(unsigned char *)str1 - *(unsigned char *)str2) && *str1)
	{
		str1++;
		str2++;
		count--;
	}
	if (ret < 0)
	{
		ret = -1;
	}
	else if (ret > 0)
	{
		ret = 1;
	}
	return ret;
}

int main()
{
	printf("%d\n", my_strncmp("abc", "abcd", 2));
	printf("%d\n", my_strncmp("abc", "abcd", 4));
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值