#include <stdio.h>
#include <string.h>
int main() {
char src[19] = "abcdef";
char *target = src;
memcpy(target+3,target,5);
printf("from memcpy : %s\n", target);
strncpy(target+3,target,5);
printf("from strncpy : %s\n", target);
memmove(target+3,target,5);
printf("from memmove : %s\n", target);
}
from memcpy : abcabcde
from strncpy : abcabcab
from memmove : abcabcab
我看到不同的函数名称,但用法是相同的,我在谷歌微软搜索的一些开发人员说,这是弃用和有害的,我想了解这些函数中的哪一个是正确的复制数据在c语言?
2条答案
按热度按时间fcg9iug31#
简单地说:
memmove
将n
字节从src
复制到dest
。memcpy
将n
字节从src
复制到dest
,只要两个区域不重叠。strncpy
将n
字节或最多\0
字节从src
复制到dest
,以先到者为准。(只要两个区域不重叠。)如果需要,它还使用\0
将目的地填充到n
字符。如果你不想考虑所有这些,就总是使用
memmove
。特别是(正如您可以看到我对它的“简单”描述的长度相对于其他人),strncpy
太奇怪和复杂,通常是有用的。[脚注:你没有问
strlcpy
,但它非常有用,并且做了你可能希望strncpy
做的事情。要演示
strncpy
和memcpy
之间的差异:这个打印
请注意,
memcpy
复制了所有内容,而strncpy
只复制了前两个字符p
和q
,然后将其余部分清零。大多数情况下,源区域和目标区域不重叠。这里有一个他们这样做的例子:
在我的机器上打印:
此代码片段尝试将字符串的前6个字符复制到字符串的最后6个副本之上。使用
memmove
,这就可以工作了,结果是abcabcdef
。但是使用memcpy
,我们得到了错误的结果,因为当它试图复制def
时,它们已经被abc
覆盖了。(实际上,它比这更复杂一点,但希望你能理解。mv1qrgav2#
memcpy和memmove的操作与数据类型无关。Linux手册页:
memcpy()函数将n个字节从内存区域src复制到内存区域dest。内存区域不得重叠。如果内存区域重叠,请使用memmove(3)。
为了解决我明显的矛盾:如果我有int 2,那就是8字节(假设我们不是在一个旧的16位系统上,int是2字节)。请注意当我尝试复制1 int时会发生什么:
结果是:
发生了什么事?当我们将指针偏移1(memcpy的第二个参数)时,它指向下一个int,但是当我们指定“1”复制时,它复制了1个字节而不是1个int。我们必须指定sizeof(int)作为要复制的字节数:
现在我们得到了我们需要的:
memcpy不允许src和dest重叠。
strncpy类似于memcpy,但用于字符串,如果在遇到指定字节数之前遇到空字符('\0'),则复制结束。