strcpy 与 memcpy

Posted

技术标签:

【中文标题】strcpy 与 memcpy【英文标题】:strcpy vs. memcpy 【发布时间】:2011-02-23 07:27:44 【问题描述】:

memcpy()strcpy() 有什么区别?我试图在程序的帮助下找到它,但两者都给出了相同的输出。

int main()

    char s[5]='s','a','\0','c','h';
    char p[5];
    char t[5];
    strcpy(p,s);
    memcpy(t,s,5);
    printf("sachin p is [%s], t is [%s]",p,t);
    return 0;

输出

sachin p is [sa], t is [sa]

【问题讨论】:

见***.com/questions/2884874/… 【参考方案1】:

printf("%s",...) 在遇到 null 时停止打印数据,因此两个输出相同。

以下代码区分strcpymemcpy

#include<stdio.h>
#include<string.h>

int main()

    char s[5]='s','a','\0','c','h';
    char p[5];
    char t[5];
    int i;
    strcpy(p,s);
    memcpy(t,s,5);
    for(i=0;i<5;i++)
        printf("%c",p[i]);
        printf("\n");
    for(i=0;i<5;i++)
        printf("%c",t[i]);

    return 0;

【讨论】:

【参考方案2】:

strcpy 在遇到 NUL ('\0') 字符时停止,memcpy 不会。这里看不到效果,因为 printf 中的%s 也停在 NUL 处。

【讨论】:

@Sachin: 将pt 初始化为某物(例如,所有空白),然后在复制后将p[3]t[3] 进行比较。 strcpy 没有超出p[2],它找到了空字符,但memcpy 按照指示复制了五个字符。 次要挑剔:strcpy 在遇到 NUL 字符(一个“L”)时停止。 NULL(两个“L”)是一个保证不指向任何有效对象的指针的编译时常量。 如果dest和src重叠,strcpy会抛出seg-fault吗?【参考方案3】:

主要区别在于memcpy() 总是复制您指定的确切字节数;另一方面,strcpy() 将复制,直到它读取一个 NUL(又名 0)字节,然后停止。

【讨论】:

【参考方案4】:

由于s 字符串中的空字符,printf 不会显示除此之外的任何内容。 pt 之间的区别在于字符 4 和 5。p 将没有任何字符(它们将是垃圾),t 将具有 'c''h'

【讨论】:

【参考方案5】: 行为差异:strcpy 在遇到NULL'\0' 时停止 性能差异:memcpy 通常比strcpy 更高效,strcpy 总是扫描它复制的数据

【讨论】:

【参考方案6】:

您的测试程序的问题是,当printf() 遇到空终止\0 时,它会停止将参数插入%s。 因此,在您的输出中,您可能没有注意到 memcpy() 也复制了字符 ch

我在 GNU glibc-2.24 中看到,(对于 x86)strcpy() 只是调用 memcpy(dest, src, strlen(src) + 1)

【讨论】:

【参考方案7】:

strcpy 将字符从源一个接一个地复制到目标,直到在源中找到 NULL 或 '\0' 字符。

while((*dst++) = (*src++));

memcpy 将数据(不是字符)从源复制到给定大小 n 的目标,与源中的数据无关。

memcpy 如果您知道源包含字符以外的内容,则应使用。对于加密数据或二进制数据,memcpy 是理想的选择。

strcpy 已弃用,因此请使用strncpy

【讨论】:

我不知道你在哪里看到 strcpy() 被弃用了。 @RohanBari 如果这个只有 MSVC 经验的人第十亿次再次谈论“已弃用的函数”,那将是皇室的愤怒【参考方案8】:

如何才能看到这种效果

编译并运行这段代码:

void dump5(char *str);

int main()

    char s[5]='s','a','\0','c','h';

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;


void dump5(char *str)

    char *p = str;
    for (int n = 0; n < 5; ++n)
    
        printf("%2.2x ", *p);
        ++p;
    

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    
        printf("%c", *p ? *p : ' ');
        ++p;
    

    printf("\n", str);

它会产生这个输出:

73 61 00 63 68  sa ch
73 61 00 00 00  sa

您可以看到“ch”被memcpy()复制,但不是strcpy()

【讨论】:

您好,我知道该帖子已过时,但我有两个问题。首先 - printf("%2.2x ", *p); - 你为什么将 printf 限制为 2.2 ?此外,我根本看不到任何点...第二 - printf("%c", *p ? *p : ' '); - 这个测试真正检查了什么?如果*p ?提前感谢您的回答! 在 printf 语句中,“x”表示“base 16”。 “2.2”的意思是:两位且只有两位。 *p 测试的意思是:“如果你命中一个空值,打印一个空格。”【参考方案9】:

strcpy 在找到源字符串的空终止符时终止。 memcpy 需要传递一个大小参数。在您提出的情况下,printf 语句在为两个字符数组找到空终止符后停止,但是您会发现 t[3]t[4] 也复制了其中的数据。

【讨论】:

以上是关于strcpy 与 memcpy的主要内容,如果未能解决你的问题,请参考以下文章

strcpy 与 strdup

strcpy 与 memcpy

strcpy与strncpy

调用 strcpy 的结果与预期不同

(C)strcpy ,strncpy与strlcpy

字符数组拷贝与strcpy函数