strcpy—strncpy-memcpy

strcpy,strncpy,memcpy

strcpy与strncpy区别

n代表可以指定字符个数进行赋值,当src字符串长度小于n,dst数组就用额外的’\0’字节填充到n长度。

strcpy实现:

1
2
3
4
5
6
7
8
9
// 为了实现链式操作,将目的地址返回,strcopy()可作为其它函数的参数(实参)
char* strcopy(char* dest,const char* src)
{
assert(dest != NULL && src!= NULL); // 指针安全检查
//对dest和src两个指针做循环移动并不断复制src内存的值到dest内存中
//当src内存中的值为’\0’时,做最后一次复制
while ((*dest++ = *src++) != '\0');
return dest;
}

strncpy实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char *strncpy(char *dest, const char *src, size_t n)  
{
assert(dest != NULL && src != NULL);
char *res = dest;
int offset = 0;
if (strlen(src) < n) //src长度小于n
{
offset = n- strlen(src);
n = strlen(src);
}
while (n--)
{
*dest++ = *src++;
}
while (offset--) //src长度小于n,用’\0’填充dest
{
*dest++ = '\0';
}
return res;

当n长度大于strlen(dest)时,使用这个函数(与 strcpy 一样),尤其需要注意,不要出现 n>strlen(dst)的情况,如果 n>strlen(dst),那么会破坏dst后面的内存。所以,使用strncpy时,最好自动添加‘\0’在结尾。

1
2
3
4
5
char buffer[BSIZE];
.
.
strncpy(buffer,name,BSIZE);
buffer[BSIZE-1]=’\0’;

strcpy与memcpy区别

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

  2. 复制的方法不同:strcpy()不指定长度,它遇到被复制字符串结束符”\0”才结束拷贝,所以容易溢出,memcpy()则是根据其第三个参数决定复制的长度;

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

memcpy实现:

1
2
3
4
5
6
7
8
9
10
11
12
//void*代表复制的数据可以是任意类型,之后进行类型间的强制转换
void* memcopy(void* dest,const void* src,size_t count)
{
assert(dest != NULL && src != NULL); // 指针安全检查
char* pDest = (char *)dest; //保存dest首地址
char* pSrc = (char *)src; //保存src首地址
while(count-- > 0) //循环count次,进行复制操作
{
*pDest++ = *pSrc++;
}
return dest; //此时,dest为复制过后内容的首地址
}

注意:

  1. strcpy 是依据 “\0” 作为结束判断的,如果 s2 的空间不够,则会引起 buffer overflow。

  2. memcpy用来在内存中复制数据,由于字符串是以“\0”结尾的,所以对于在数据中包含“\0”的数据只能用memcpy。

  3. Strncpy和memcpy很相似,只不过它在一个终止的空字符处停止。当n>strlen(s1)时,给s2不够数的空间里填充“\0”;当n<=strlen(s1)时,s2是没有结束符“\0”的。

    这里隐藏了一个事实,就是s2指向的内存一定会被写n个字符。

所以总的来说注意:

  1. dest指向的空间要足够拷贝;使用strcpy时,dest指向的空间要大于等于src指向的空间;使用strncpy或memcpy时,dest指向的空间要大于或等于n。

  2. 使用strncpy或memcpy时,n应该大于strlen(src),或者说最好n >= strlen(src)+1;这个1 就是最后的“\0”。

  3. 使用strncpy时,确保dest的最后一个字符是“\0”。

参考


strcpy—strncpy-memcpy
http://zanderchan666.github.io/2023/09/15/strcpy—strncpy-memcpy/
作者
Zander
发布于
2023年9月15日
许可协议