C语言strcpy和strncpy的用法和区别(包括如何模拟实现)
strcpy和strncpy都是字符串拷贝函数,他们的区别就是后者限制了拷贝的长度(字节大小),就像 strcpy(a , b) 是将b的内容复制然后粘贴到a里面去,a原本的内容就会被覆盖,而 strncpy(a , b , n) 也是这样,只不过多了一个参数 n,这个n就是拷贝的字节大小,假如 n为5,而b的字节大小为10(也就是长度为10),那么b只有前五个字符能被拷贝到a里面去。
下面我们通过代码来理解一下他们的具体含义:
#include<stdio.h>
#include<string.h>
int main()
{
char a[] = "hello";
char b[] = "12345";
char c[] = "hello";
//我们用strcpy函数试试
strcpy(a , b);
puts(a);
//我们再用strncpy函数试试
int n = 3;
strncpy(c , b , n); //这里的n为字节数,n=3意思是只拷贝b的前三个字符到c中去
puts(c);
}
运行结果:
可以看到,我们用strcpy(a , b)是把b的所有内容拷贝到a中去了,而用strncpy(a , b , n)只拷贝了b的前n个字节的内容,在这个例子中也就是前三个字符
特殊情况:当n大于b的长度时并且小于a的长度,那么字符串b的内容全部都会被拷贝到a里面去; 如果n比a和b的长度都大,那么此时就要注意一下a的长度了,请确保字符串a的长度足够大
例如:
#include<stdio.h>
#include<string.h>
int main()
{
char a[20] = "hello";
char b[] = "123456789";
int n = 12;
strncpy(a , b , n);
puts(a);
}
运行结果:
#include<stdio.h>
#include<string.h>
int main()
{
char a[20] = "hello";
char b[] = "123456789";
int n = 9;
strncpy(a , b , n);
puts(a);
}
运行结果:
下面我们看看如何模拟实现strpcy和strncpy这两个字符串拷贝函数
首先是模拟实现strcpy函数
#include<stdio.h>
char* my_strcpy(const char* p1,const char* p2) //注意返回类型为指针
{
char* a = p1;
char* b = p2;
int i = 0;
while(*a = *b) //当 *b 等于 '\0'时,*a = *b 这个表达式的结果就为0,0为假所以推出while循环
{
a++;
b++;
}
/*上面的while循环等价于
while(*b != '\0')
{
*a = *b;
a++;
b++;
} */
}
int main()
{
char a[20] = "hello world";
char b[] = "123456";
printf("拷贝前a:%s\n", a);
char* pt = my_strcpy(a,b); //注意我们用指针变量来接受返回的地址
printf("拷贝后a:%s\n", a);
}
运行结果:
下面是模拟实现strncpy函数
#include<stdio.h>
char* my_strncpy(const char* p1,const char* p2, const int n) //注意返回类型为指针
{
char* a = p1;
char* b = p2;
int count = n;
while(*a != '\0' && *b != '\0' && count) //*a,*b,count都不为0时执行循环
{
*a++ = *b++; //等价于*a = *b; *a++; *b++;
count--;
}
//注意考虑特殊情况,当n大于a的长度时,b中的'\0'是没有拷贝到a里面去的
//所以我们拷贝结束的位置手动添加一个 '\0'
*a = '\0'; //当n小于a时这句话也不会对程序产生影响
}
int main()
{
char a[20] = "hello world";
char b[] = "123456";
int n = 5; //只拷贝b的前五个字节的内容
printf("拷贝前a:%s\n", a);
char* pt = my_strncpy(a, b, n); //将b中前五个字节的内容拷贝到a
printf("拷贝后a:%s\n", a);
}
运行结果:
因为n等于5,所以只拷贝了b的前五个字符到a中去,此时a的前五个字符被覆盖