Copying类库函数的模拟实现 (1
一、 strcpy
1.strcpy库函数的介绍
在接触string内的库函数时,我们了解的第一个库函数就是strcpy,它是把一个以双引号的字符串,拷贝到目标的地址空间中。
strcpy有以下几个使用要点
1.在调用strcpy库函数的时候,源字符串要以’\0’结尾。
2.使用strcpy库函数的时候,也会将’\0’拷贝到目标字符串中,并作为结束标志。
3.目标字符串的空间要足够大,放得下源字符串。
2.strcpy库函数的模拟思路及实现代码
在C++ Reference我们可以看到关于strcpy库函数的返回类型和参数:
char * strcpy ( char * destination, const char * source );
它的返回类型是char*,也就是目标的起始地址;参数分别为目标的起始地址和源字符串的起始地址,由于我们不期望源字符串被改变,所以用const进行修饰。
我们先来看一个调用strcpy库函数实现功能的代码
int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}
运行结果为:
str1: Sample string
str2: Sample string
str3: copy successful
现在我们开始尝试模仿strcpy库函数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* sou)
{
char* ret = dest;
assert(dest != NULL);//assert断言,目标与源字符串为空,下面代码不予执行
assert(sou != NULL);
while (*dest++ = *sou++)//简化后的写法
{
;
}
return ret;//返回目标起始地址
}
int main()
{
char arr[20] = { '0'};
char* p = "hello world";
my_strcpy(arr, p);
printf("%s\n", arr);
return 0;
}
上述代码的核心是实现字符的逐个拷贝,即:
while (*dest++ = *sou++)
{
;
}
在最初尝试的时候,我们会写出以下代码片段:
while (*sou!='\0')
{
*dest = *sou;
dest++;
sou++;
}
简化的代码只是让形式看起来更简洁,实际的功能并未改变。
这样我们就完成了对库函数strcpy的模拟。
附上C++ Reference链接:strcpy C++ Reference
二、strcnpy
1.strncpy库函数的介绍
strncpy函数的功能与strcpy相似,只不过它只拷贝限定长度的字符。
strncpy有以下几个使用要点:
1.当sou字符串长度小于n时,那么当字符串被拷贝后,剩余部分将用空字节填充,直到达到n个。
2. strncpy不会向dest追加’\0’,除非它将’\0’拷贝进去。
3.sou和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符。
2.strncpy库函数的模拟思路及实现代码
在C++ Reference我们可以看到关于strncpy库函数的返回类型和参数:
char * strncpy ( char * destination, const char * source, size_t num );
它的返回类型同样是char*,也就是目标的起始地址;参数分别为目标的起始地址和源字符串的起始地址,此外还多了需要拷贝字符的个数。
我们先来看一个调用strncpy库函数实现功能的代码:
int main ()
{
char str1[]= "To be or not to be";
char str2[40];
char str3[40];
/* copy to sized buffer (overflow safe): */
strncpy ( str2, str1, sizeof(str2) );
/* partial copy (only 5 chars): */
strncpy ( str3, str2, 5 );
str3[5] = '\0'; /* null character manually added */
puts (str1);
puts (str2);
puts (str3);
return 0;
}
运行的结果如下:
To be or not to be
To be or not to be
To be
现在我们开始尝试模拟strncpy库函数
char* my_strncpy(char* dest, const char* sou,size_t num)
{
char* ret = dest;
assert(dest != NULL);
assert(sou != NULL);
while (num--)//拷贝代码的实现
{
*dest++ = *sou++;
}
if (*dest != '\0')
*dest = '\0';//给它补上结束的标志
return ret;
}
int main()
{
char arr[30] = "Practice makes perfect!";
char* p= "excellent_";
my_strncpy(arr+15, p,9);
printf("%s\n", arr);
return 0;
}
运行的结果是
可以看出我们只是对my_strcpy做了一些修改,主要是针对拷贝字符个数进行的改动。另外,我们要考虑到’\0’的问题,要在最后主动为他添一个’\0’。
这样我们就完成了对库函数strncpy的模拟。
附上C++ Reference链接:strncpy C++ Reference