strcpy和strncpy的模拟实现

要想模拟实现这两个库函数,首先得明白它们到底是干嘛的,然后考虑它有哪些需要注意的地方,最后才是具体的去实现每一个细节。

strcpy:

功能:把源字符串src里面的字符串拷贝到目标字符串dest中去

注意:1、目标字符串要有足够大的空间可以容下源字符串。

   2、目标字符串要是可修改的。

现在我们来讨论一下它的具体实现。首先考虑它的参数,既然是把一个字符串拷到另一个字符串中去,那我们就必须得知道两个字符串的首元素地址,那么,参数的类型就是char *,此时要注意到只是把源字符串拷到目标字符串中,源字符串本身是不需要做任何改变的。所以,第二个参数可用const修饰。其次来考虑它是否需要返回一个值,若需返回,那么它的返回值类型是什么?(这个我在代码中再来讲解)

下边来看代码

#include <stdio.h>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>

char* my_strcpy(char *dest, const char *src)
{
	assert(dest != NULL);
	assert(src != NULL);
	//判断两个指针时候为空指针,若为空,后边对它进行解引用的话就会使程序崩溃
	char *ret = *dest;//创建一个临时指针来记住目标字符串的首元素地址
	while (*dest++ = *src++)//当把字符串src的‘\0’拷过去之后,while里边就是0了,循环就停下来了
	{
		;
	}
	return ret;
}
可以看到这里有一个char *类型的返回值,其实,不用返回值也可以实现我们的字符串拷贝,那为什么还要加个返回值呢? 为了实现链式访问。

下边举个例子:

#include <stdio.h>
#include <assert.h>

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 buf1[20] = "abcdefghijk";
	char buf2[] = "mnopq";
	my_strcpy(buf1, buf2);
	printf("%s\n", buf1);
	return 0;
}

运行结果为:


strncpy:

其功能也是字符串拷贝,它比strcpy多了一个参数n(要拷贝的字符的个数)。所以我们需要判断n与源字符串src长度(length)哪个大并对其分别进行处理。需要说明的是,这里的长度是将'\0'也包括进来的。

下边来讨论n与len作比较的三种情况。

1、n<length

这是最好处理的一种情况,只要将源字符串的前n个字符拷贝到目标字符串dest中就行了。

2、n=length

此种情况就相当于strcpy

3、n>length

这种情况相对来说要麻烦一点,当把源字符串拷完了之后多出去的需拷几个字符就用‘\0’代替

注意:

1、目标字符串要有足够大的空间可以容下源字符串。

2、目标字符串要是可修改的。

下面看代码:

#include <stdio.h>
#include <assert.h>

char *my_strncpy(char *dest, const char *src, int n)
{
	assert(dest != NULL);
	assert(src != NULL);
	char *ret = *dest;
	//此循环用于处理n小于或等于源字符串src的长度(length)的情况
	while (n && (*src))//当n等于0或者*src为'\0'的时候while循环停下
	{
		*dest++ = *src++;
		n--;
	}
	//此循环用于处理n大于源字符串src的长度的情况

	while (n > 0)//若进入了该循环说明上一个循环是因为*src='\0'而退出的,及n>length
	{
		*dest++ = 0;
		n--;
	}
	
	return ret;
}

下边举个例子将三种情况都看一下

#include <stdio.h>
#include <assert.h>

char *my_strncpy(char *dest, const char *src, int n)
{
	assert(dest != NULL);
	assert(src != NULL);
	char *ret = *dest;
	while (n && (*src))
	{
		*dest++ = *src++;
		n--;
	}
	while (n > 0)
	{
		*dest++ = 0;
		n--;
	}
	
	return ret;
}
int main()
{
	char dest[20] = "abcdefghijk";
	char src[] = "hello";
	my_strncpy(dest, src, 3);
	printf("%s\n", dest);
	my_strncpy(dest, src, 6);
	printf("%s\n", dest);
	my_strncpy(dest, src, 8);
	printf("%s\n", dest);
	return 0;
}
运行结果

虽然第二个和第三个结果看起来一样,事实上,在内存里边存的是不一样的,调试,在窗口打开内存,对my_strncpy函数取地址会出现这样的一串数据,看图


发现当源字符串被拷贝完了之后,之后的三个字符都被拷贝成了‘\0’


总结:

strcpy只是拷贝字符串,但不限制拷贝的数量,很容易造成缓冲溢出。strncpy相对要安全一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值