strcpy的原型为extem char *strcpy(char *dest,const char *src);它包含在头文件string.h中,它的返回指向dest的指针,其功能是把src所指由NULL结束的字符串复制到dest所指的数组中。值得注意的是,src和dest所指内存区域不可以重叠,且dest必须有足够的空间来容纳src的字符串,src字符串尾的字符串结束标识符'\0'也会被复制过去。
char *strcpy(char *strDest,const char *strSrc);
{
assert((strDest!=NULL)&&(strSrc!=NULL));
if (strDest==strSrc)
return strDest;
char *address=strDest;
while((*strDest++=*strSrc++)!='\0')
return address;
}
C语言的assert()在<assert.h>中,当使用assert时,给它一个参数,即一个判断为真的表达式。strcpy能把strSrc的内容复制到strDest,返回类型为char*主要是为了实现链式表达式。例如:
int length=strlen(strcpy(strDest,"hello world"));
strcpy(strDest,strcpy(strDest1,strSrc));
可以将strSrc复制到strDest1与strDest中,也就是说,可以将函数的返回值做为另一个函数的参数。
程序代码示例如下:
#include<stdio.h>
#include<string.h>
int main()
{
char str[]="hello world";
strcpy(str,"h");
printf("%s\n",str);
printf(”%c\n",str[3]);
return 0;
}
程序输出结果:
h
1
因为strcpy将K以及\0一直复制到str的地址空间内,覆盖了hello world字符串(hello world是在栈区上分配的内存空间),但是后续的字符并没有被替换,如str[3]仍然是1。将char str[]="hello world";改为char* str="hello world";是不允许的,因为str此时是一个指针变量。
再例如:
#include<stdio.h>
#include<string.h>
int main()
{
char s[]="123456789";
char d[]="123";
strcpy(d,s);
printf("%s\n%s\n",d,s);
return 0;
}
程序输出结果:
123456789
56789
上例中,数组s和数组d在内存中的存储结构如图所示。
图1 数组s和数组d在内存中的存储结构
strcpy的功能就是把“源字符串”s复制到“目的字符串”d,直到遇到“源字符串”的结束标识符‘\0’,复制后的数组d和数组S的存储结构如图2所示。
图2 复制后的数组S和数组d的存储结构
所以d变为“123456789”,s变为“56789”。
程序代码示例如下:
void test()
{
char string[10];
char* str1="0123456789";
strcpy(string,str1);
}
上例中,字符串str1需要11个字节才能存放下(包括末尾的'\0'),而string只有10个字节的空间,所以执行strcpy会导致数组越界。
程序代码示例如下:
void test()
{
char string[10],str1[10];
int i;
for(i=0;i<10;i++)
str1[i]='a';
strcpy(string,str1);
}
上例中字符数组str1没有结尾符'\0',不能在数组内结束,执行strcpy(string,str1)语句,会使从str1内存起复制到string内存的字节数具有不确定性。
程序代码示例如下:
void test(char* str1)
{
char string[10];
if(strlen(str1)<=10)
strcpy(string,str1);
}
上例中if(strlen(str1)<=10)应改为if(strlen(str1)<10),因为strlen的结果未统计'\0',所占用的1个字节。