strcpy、strncpy 和 memcpy

(1)char* strcpy(char* dest, const char* src);

strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。

char * strcpy(char * dest, const char * src) // 实现src到dest的复制
{
	if((src==NULL)||(dest==NULL))
	{
		return NULL;
	}
	char* strDest=dest;
	while((*dest++=*src++)!='\0'); //先拷贝后判断,这样就不用在拷贝完了后,再加一句 *strDest = '\0';(即加一个结束符),因为字符串结束时已拷贝了
	return strDest;
}

例如: char a[100],b[50];
strcpy(a,b); //没有问题
strcpy(b,a); //注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。


(2)void *memcpy( void *dest, const void *src, size_tcount);

memcpy用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束。

void *memcpy(void *memTo, const void *memFrom, size_t size)
{
	if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效
	return NULL;
	char *tempFrom = (char *)memFrom;             //保存memFrom首地址
  char *tempTo = (char *)memTo;                  //保存memTo首地址      
  while(size -- > 0)                //循环size次,复制memFrom的值到memTo中
       *tempTo++ = *tempFrom++ ;  
  return memTo;
}

例如: char a[10],b[5]; 
memcpy(b, a, sizeof(b));   //注意如果用sizeof(a),会造成b的内存地址溢出


(3)strcpy和memcpy的区别

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度

3、用途不同。 通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

(4)memcpy异常情况

memcpy在实现的时候,是“从前拷贝”,还是“从后拷贝”?如果是不知道。那么,有一天你使用memcpy(p+5,p,10);这个语句的时候,就可能会获得错误的结果。
1. 失败情况:copy的区域重叠。
例如
memcpy(a, b, 10);
如果指针b在a之前且距离小于10,则实际copy结果没有达到预计目标,
这个和memcpy的实现有关。这种情况需要使用memmove。
2. 异常情况
当copy越界时,可能会出现程序异常。
如果是在栈上,那可能更麻烦,因为它出现异常的位置往往不是真的有问题的位置。
memcpy进行内存拷贝时有可能发生内存读写错误,比如length大于要拷贝的空间或大于目的空间,可能发生:
int *p = new[10];
memcpy(dst, p, 20);//20超过10了,由于p是堆内分配的,所以超过的部分不属于进程空间,发生内存读写错误。而
int p[10];
memcpy(dst, p, 20);//不发生错误,因为定义的变量在栈里,p超过10位仍属于进程空间。

(5)strncpy的用法

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

用法:#include <string.h>

功能:把src所指由NULL结束的字符串的前n个字节复制到dest所指的数组中。

说明:

    如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。
    如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。
    src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
    返回指向dest的指针。

举例:

      // strncpy.c
      #include <syslib.h>
      #include <string.h>
      main()
      {
        char *s="Golden Global View";
        char *d="Hello, GGV Programmers";
        char *p=strdup(s);
        
        clrscr();
        textmode(0x00);  // enable 6 lines mode
                
        strncpy(d,s,strlen(s));
        printf("%s\n",d);
        
        strncpy(p,s,strlen(d));
        printf("%s",p);
        
        getchar();
        return 0;
      }

strncpy()函数不会复制字符串后面的结束符\0,因此要给它补上:

char a[]="www.ok2002.com";  
char b[20]; 
strncpy(b,a,strlen(a));//strncpy函数不会复制字符串后面的'\0' 
b[strlen(a)]='\0';//因此要程序员给它补上 
cout<<b<<endl; 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值