在C语言中,strcpy
和 strncpy
是处理字符串时常用的两个函数,但它们在处理字符串复制时的行为和安全性上有所不同。下面,我将简要介绍这两个函数的功能,并提供它们的自实现(即不使用标准库函数,自己编写实现这些功能的代码)。
strcpy的复现
char *myStrcpy(char *des,char *src)
{
char *back = des;
if(des == NULL || src == NULL){
return NULL;
}
while(*src != '\0'){
*des = *src;
des++;
src++;
}
*des = '\0';
return back;
}
char *myStrcpy2(char *des,char *src)
{
char *back = des;
if(des == NULL || src == NULL){
return NULL;
}
while(*src != '\0'){
*des++ = *src++;
}
*des = '\0';
return back;
}
char *myStrcpy3(char *des,char *src)
{
char *back = des;
if(des == NULL || src == NULL){
return NULL;
}
while((*des++ = *src++) != '\0')
*des = '\0';
return back;
}
上述共提供了三个复现代码,逻辑相同,区别主要体现在while循环的书写方式,从第一个到第三个,越来越简单。在循环后加入 *des = '\0'; 主要是因为strcpy
函数会将源字符串(包括空终止符 '\0')复制到目标字符串中。而在我们的复现代码的循环中是没有 ' \0 ' 的,因此要手动添加。
同时在循环复制开始之前,需要先判断des和src两个指针是否为空。若为空,直接返回空,复制失败。
strcpy的复现
代码如下:
char *myStrncpy(char *des,char *src,int count)
{
char *back = des;
if(des == NULL || src == NULL){
return NULL;
}
while((*src != '\0') && count > 0){
*des++ = *src++;
count--;
}
if(count > 0){
while(count>0){
*des++ = '\0';
count--;
}
return back;
}
*des = '\0';
return back;
}
- 首先检查
des
和src
是否为NULL
。如果任一为NULL
,则函数立即返回NULL
。这是一个重要的安全特性,防止在空指针上解引用导致的未定义行为。
- 接着使用一个
while
循环来复制字符,直到遇到源字符串的结尾(\0
)或已达到count
指定的最大复制次数。 - 在循环内部,将
src
指向的字符复制到des
指向的位置,然后递增src
和des
指针,并递减count
。 - 循环结束后,如果
count
仍然大于 0,说明源字符串的长度小于指定的字符数,需要在目标字符串的末尾添加足够的空字符('\0')直到达到指定的字符数。此时,使用一个内部的while
循环来在剩余的空间中填充空字符\0
,直到count
减至 0。 - 如果在复制完所有源字符串字符后
count
恰好为 0(即源字符串长度等于或大于count
),则循环结束后,源字符串的末尾可能没有空字符。因此,代码显式地在des
指向的当前位置(即最后一个复制的字符之后)添加了一个空字符\0
。