【问题标题】:strcpy vs. memcpystrcpy 与 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]

【问题讨论】:

标签: c memcpy strcpy


【解决方案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] 也复制了其中的数据。

            【讨论】:

              猜你喜欢
              • 2014-09-17
              • 2021-06-23
              • 2012-12-10
              • 2014-09-19
              • 2011-05-23
              • 2013-02-04
              • 1970-01-01
              • 2021-08-11
              • 2011-10-19
              相关资源
              最近更新 更多