C语言一些字符串函数的模拟实现

一、strcpy库函数模拟实现

在模拟实现之前,我们先介绍一下strcpy库函数的功能,首先它的大体功能是将一个字符串的内容复制到另一个字符串数组中,这个字符数组一定要有能力去存储这些复制过来的字符串,否则会报错,复制过程中会将源字符串末尾的\0字符也会复制过来。

通过调试我们也可以看出这点。

观察strcpy库函数,发现它有两个参数都是char*,返回值的类型也是char*,为什么这样设计?目的就是将源字符串内容拷贝放到目的字符串数组中,并返回目的字符串首元素的地址,接下来我们就开始实现,请看代码:

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);//保证两个指针的有效性
	char* ptr = dest;//记住目的字符串首元素地址,便于返回
	while (*dest++ = *src++)//一个个字符拷贝过去,循环直到把'\0'拷贝过去,结束循环
		;//空语句,while循环需要这个语句,但我们不需要它做事
	return ptr;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = "xxxxxxxxxxxx";
	printf("%s\n", my_strcpy(arr2, arr1));
	return 0;
}

二、strncpy库函数模拟实现

strncpy库函数的功能和strcpy的差不多,但strncpy函数多了一个参数来控制拷贝的字符的个数,

这个参数是多少,就拷贝多少个字符,如果拷贝的字符数大于源字符串的长度就以'\0'填充。

这两幅图是对上述文字内容的解释。接下来,我们就去实现它。请看代码:

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);//判断指针的有效性
	char* ptr = dest;//记住目的字符串首元素地址,便于返回
	while (num--)//控制实现复制num个字符
	{
        //如果num不为零时src就走到头了或者src指向的是空串,则*dest赋值为'\0'
		if (*src == '\0') 
			*dest++ = '\0';
		else
			*dest++ = *src++;
	}
	return ptr;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = "xxxxxxxxxxxxxxxxx";
	printf("%s\n", my_strncpy(arr2, arr1, 10));
	return 0;
}

三、strcat库函数模拟实现

strcat库函数可以用来实现字符串追加。

它由两个参数,它的作用是将源字符串的内容在目的字符串第一次出现'\0'的位置处往后追加,直到将源字符串追加完。前提是目的字符串数组有能力去让源字符串追加上去(即内存空间足够大),返回目的字符串首元素地址。

通过调试,我们发现,strcat库函数也会把源字符串末尾的'\0'拷贝进去。接下来,我们就开始模拟实现,请看代码:

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ptr = dest;//记住目的字符串首元素地址,便于返回
	while (*dest) //通过循环找到目的字符串中'\0'的位置
		dest++;
	while (*dest++ = *src++)//一个个字符追加过去,循环直到把'\0'追加过去,结束循环
	;//空语句,while循环需要这个语句,但我们不需要它做事
	return ptr;
}
int main()
{
	char arr1[] = "def";
	char arr2[20] = "abc\0xxxxxxxx";
	printf("%s\n", my_strcat(arr2, arr1));
	return 0;
}

四、strncat库函数模拟实现

strncat库函数的功能也和strcat的差不多,strncat函数多了一个参数来控制追加的字符的个数。

但有一点不同的是,如果num为n,则会多追加一个字符'\0',即追加(n+1)个字符,如果num大于源字符串的长度时,多余的部分只补一个'\0',这一点是与strncpy的规则不同。

了解了以上的功能后,我们就开始模拟实现它,请看代码:

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* ptr = dest;//记住目的字符串首元素地址,便于返回
	while (*dest)//找到目的字符串第一个'\0'的位置
		dest++;
	while (num--)
	{
		if (*src == '\0')//如果num不为零时src就走到头了或者src指向的是空串,则跳出循环
			break;
		*dest++ = *src++;
	}
	*dest = '\0';//最后追加一个'\0'过去
	return ptr;
}
int main()
{
	char arr1[] = "def";
	char arr2[20] = "abc\0xxxxx";
	printf("%s\n", strncat(arr2, arr1,10));
	return 0;
}

五、strcmp库函数模拟实现

strcmp库函数的功能是比较两个字符串的大小,若字符串1大于字符串2就返回一个大于0的数,如果字符串1小于字符串2就返回一个小于0的数,如果字符串1等于字符串2就返回0,那它们是怎么比较的呢?我们知道每个字符在ASCII码表中都有一个对应的十进制的数,从第一个字符开始,根据ASCII码的值判断大小,若ASCII码一样,则比第二个字符,若比到字符串的末尾还一样就说两个字符串相等。

strcmp库函数有两个char*类型的参数,分别指向要比较的字符串首元素的地址,返回一个整形的值。

下面,开始写代码去实现这个函数。请看代码:

#include <assert.h>
#include <stdio.h>
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);//判断指针的有效性
	while (*str1 == *str2)//若对应位置字符相等,则向后接着比
	{
        //1.两个都是空串 2.同时比到字符串末尾了 这两种情况都说明两个字符串相等 返回0
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
    //这里循环跳出来了说明两个字符串不完全匹配,必定有一大一小,直接相减即可
	return *str1 - *str2;
}
int main()
{
	char arr1[] = "abd";
	char arr2[] = "abc";
	printf("%d\n", my_strcmp(arr1, arr2));
	return 0;
}

六、strncmp库函数模拟实现

strncmp库函数的功能也和strcmp的差不多,strncmp函数多了一个参数来控制比较的字符的个数。

num的值如果大于要比较的两个字符串的长度的最大值则功能就如同strcmp一样,反之就按num个字符进行比较,如果没到num时就比较出来大小了就直接返回就行。

下面进行实现,请看代码:

#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);//判断指针有效性
	while (*str1 == *str2)//若对应位置字符相等,则向后接着比
	{
		num--;//移动一次num自减1
        //1.两个都是空串 
        //2.同时比到字符串末尾了 
        //这两种情况不管比多少位都说明两个字符串相等,返回0 
        //3.如果没比到最后,num提前为0了且前面比的几位数都是相等的,则返回0
		if (*str1 == '\0' || num == 0)
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char arr1[] = "abcded";
	char arr2[] = "abcdedr";
	printf("%d\n", my_strncmp(arr1, arr2, 5));//结果为0
	return 0;
}

七、strstr库函数的模拟实现

这个函数有两个形参,都是char*类型的,返回一个char*类型的指针,功能是函数返回字符串str2在字符串str1中第⼀次出现的位置。若str2在str1中没有出现过则返回NULL。字符串的比较匹配不包含 \0 字符,以 \0 作为结束标志。

相比大家已经理解了它的功能,接下来我们开始实现它,请看代码:

#include <stdio.h>
#include <assert.h>
const char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);//判断指针有效性
	if (!*(str2))  //如果str指向的字符串为空字符串,就返回str1
		return str1;
	char* cur = str1;
	char* s1 = NULL, * s2 = NULL;
	while (*cur)
	{
		s1 = cur;   //指向第一个字符串首元素地址
		s2 = str2;  //指向第二个字符串首元素地址
		while (*s1 == *s2 && *s2 != '\0') //如果相等,同时向前进
		{
			s1++;
			s2++;
		}
		//直到它们不相等,若此时*s2为'\0'就说明
        //str2指向的字符串一定完全在str1指向的字符串中
		if (*s2 == '\0')
			return cur;
		//否则让cur指针加一,再赋给s1,继续比
		cur++;
	}
	//直到*cur为'\0'还没有比较出来就说明str2所指向的字符串不在或不完全在str1中
	//返回NULL
	return NULL;
}
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcccddasd";
	char arr2[] = "ccd";
	printf("%s\n",my_strstr(arr1,arr2));
}

八、strlen库函数的模拟实现

strlen库函数是用来求一个字符串长度的。

它的参数只有一个即要求字符串的首元素地址,返回值是size_t类型的,即无符号整形,因为长度不可能小于0所以返回值用size_t类型。

它计算长度是计算到字符串中'\0'之前的字符个数。

接下来我们用具体代码实现它,有3种方法可供大家参考,请看代码:

//第一种方法---计数器法
size_t my_strlen(const char* str)
{
	assert(str);//判断指针有效性
	int count = 0;//计数器
	while (*str)//判断是否走到'\0'位置上去
	{
		count++;//如果没有计数器就加一
		str++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef\0";
	printf("%zd\n",my_strlen(arr));//6
	return 0;
}
//第二种方法---指针减指针
size_t my_strlen(const char* str)
{
	assert(str);//判断指针有效性
	char* ptr = str;//设置一个临时指针
	while (*ptr)//让这个指针走到字符串末尾
	{
		ptr++;
	}
	return ptr - str;//末尾指针减去起始指针就得到中间元素的个数
}
int main()
{
	char arr[] = "abcdef\0";
	printf("%zd\n", my_strlen(arr));//6
	return 0;
}
//第三种方法---递归
size_t my_strlen(const char* str)
{
	assert(str);//判断指针有效性
	if (*str == '\0')//终止条件
		return 0;
	return 1 + my_strlen(str + 1);//把这个字符串拆成两部分
}
int main()
{
	char arr[] = "abcdef\0";
	printf("%zd\n", my_strlen(arr));//6
	return 0;
}

以上就是所有内容了,祝大家天天开心!
 

  • 36
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值