strcpy函数详解及strcpy与strncpy比较

来源:互联网 发布:少年犯之七人 知乎 编辑:程序博客网 时间:2024/05/17 20:30
复制代码
复制代码
复制代码
复制代码
 1 #include<stdio.h> 2 #include <assert.h>  5 void myStrcpy(char* Dest, const char *Src) 6 { 7     assert((Dest!= NULL)&&(Src!=NULL)); 8     while((*Dest = *Src)!='\0') 9     {10         Dest++;11         Src++;12     }13 }14 15 int main()16 {17     char dest[] = "helloworld";//注意18     char* src = "hello";19     myStrcpy(dest, src);20     printf("%s",dest);21     return 0;22 }
复制代码
复制代码

 

 
复制代码
复制代码

注意:在第17行中,我们用的是字符数组,因为如果用字符指针的话,字符常量存放在常量区,指针会指向这个地址,不能通过修改指针指向内容修改字符串。如果用字符数组的话,会把“helloworld“内容复制到数组中去,可以被修改。

 

strcpy函数原型:

复制代码
1 char *strcpy(char *strDest, const char *strSrc)2 {3   assert((strDest != NULL) && (strSrc != NULL)) ;4   char *address = strDest;5   while((*strDest++ = *strSrc++) != '\0')   //复制直达源串结束6      NULL;7   return address;         8 }
复制代码


strcpy函数和strncpy函数的原型介绍在我的另一篇文章中介绍了,见strcpy,strncpy,strlen等函数原型

strcpy:字串复制

  原型:char *strcpy(char *dest, char *src);

  功能:把src所指由'\0'结束的字符串复制到dest所指的数组中。

  说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

  返回指向dest的指针。

  注意:当src串长度>dest串长度时,程序仍会将整个src串复制到dest区域,可是dest数组已发生溢出。

  因此会导致dest栈空间溢出以致产生崩溃异常。如果不考虑src串的完整性,可以把dest数组最后一元素置为NULL,从dest串长度处插入NULL截取字串。


strncpy:字串复制

  原型:char * strncpy(char*dest, char *src, size_t n);

  功能:将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。

  说明:

  如果n > dest串长度,dest栈空间溢出产生崩溃异常。

  否则:

  1)src串长度<=dest串长度,(这里的串长度包含串尾NULL字符)

  如果n=(0, src串长度),src的前n个字符复制到dest中。但是由于没有NULL字符,所以直接访问dest串会发生栈溢出的异常情况。

  如果n = src串长度,与strcpy一致。

  如果n = dest串长度,[0,src串长度]处存放src字串,(src串长度, dest串长度]处存放NULL。

  2)src串长度>dest串长度

  如果n =dest串长度,则dest串没有NULL字符,会导致输出会有乱码。如果不考虑src串复制完整性,可以将dest最后一字符置为NULL。

  综上,一般情况下,使用strncpy时,建议将n置为dest串长度(除非你将多个src串都复制到dest数组,并且从dest尾部反向操作),复制完毕后,为保险起见,将dest串最后一字符置NULL,避免发生在第2)种情况下的输出乱码问题。当然喽,无论是strcpy还是strncpy,保证src串长度<dest串长度才是最重要的。

总结:这个函数会出现三种情况:
1、num<source串的长度(包含最后的'\0'字符):那么该函数将会拷贝source的前num个字符到destination串中(不会自动为destination串加上结尾的'\0'字符);
2、num=source串的长度(包含最后的'\0'字符):那么该函数将会拷贝source的全部字符到destination串中(包括source串结尾的'\0'字符);
3、num>source串的长度(包含最后的'\0'字符):那么该函数将会拷贝source的全部字符到destination串中(包括source串结尾的'\0'字符),并且在destination串的结尾继续加上'\0'字符,直到拷贝的字符总个数等于num为止。


以下是一个用strncpy()函数拷贝字符串的一部分的例子:

  1. #include<stdio.h>  
  2. #include<string.h>  
  3.   
  4. int main()  
  5. {  
  6.     char * source_str = "THIS IS THE SOURCE STRING" ;  
  7.    
  8.     char dest_str1[40] = {0};  
  9.     char dest_str2[40] = {0};  
  10.   
  11.  /* Use strncpy() to copy only the first 11 characters. */  
  12.     strncpy(dest_str1 , source_str , 11);  
  13.     printf("dest_str1 is now: %s \n" , dest_str1);  
  14.   
  15. /*Now, use strncpy() to copy only the last 13 characters. */  
  16.     strncpy(dest_str2, source_str + (strlen(source_str)-13) , 13);  
  17.     printf("dest_str2 is now: %s \n" ,dest_str2);  
  18.   
  19.     return 0;  
  20. }  


在上例中,第一次调用strncpy()函数时,它将源字符串的头11个字符拷贝到dest_str1中,这是一种相当直接的方法,你可能会经常用到。第二次调用strncpy()函数时,它将源字符串的最后13个字符拷贝到dest_str2中,其实现过程为:
 

   (1)用strlen()函数计算出source_str字符串的长度,即strlen(source_str)。
    (2)将source_str的长度减去13(13是将要拷贝的字符数),得出source_str中剩余的字符数,即pstrlen(source_str)-13。
    (3)将strlen(source_str)-13和source_str的地址相加,得出指向source_str中倒数第13个字符的地址的指针,即source_str+(strlen(source_str)-13)。这个指针就是strncpy()函数的第二个参数。
    (4)在strncpy()函数的第三个参数中指定要拷贝的字符是13。

0 0
原创粉丝点击