用于结构复制的memcpy和strncpy的区别

时间:2014-12-01 19:10:13

标签: c struct memcpy strncpy

我有以下代码。我试图将结构复制到字符串。我想了解为什么输出在strncpy和memcpy之间变化。

#include <stdio.h>
#include<string.h>
struct a{
    int len;
    int type;
};
int main(){
    struct a aa={98,88};
    char str[10]="";
    char str2[10]="";

    strncpy(str,&aa,sizeof(struct a));
    memcpy(str2,&aa,sizeof(struct a));
    for(int i=0;i<10;i++)printf("%2d",str[i]);
    printf("\n");
    for(int i=0;i<10;i++)printf("%2d",str2[i]);

    return 0;
}

以下是输出:

98 0 0 0 0 0 0 0 0 0
98 0 0 088 0 0 0 0 0

我理解strncpy将复制,直到它达到'\ 0'(或大小限制),但我在结构中没有'\ 0'值。有人可以帮我理解这一点。 这样做的目的:尝试通过网络发送结构。虽然我打算实现序列化,但我想了解行为

编辑: 1)Keith Thompson建议

以下是生成的警告。

incompatible pointer types passing 'struct a *' to parameter of type 'const char *' [-Wincompatible-pointer-types]

2)我修改了一些代码以使用int数组:

(把它作为参考。我理解在这种情况下,memcpy在数组的前两个元素中复制struct的变量,因为大小对于struct变量是足够的。)

#include <stdio.h>
#include<string.h>
struct a{
    int len;
    int type;
};
int main(){
    struct a aa={98,88};
    int str[10]={0};
    int str2[10]={0};

    strncpy(str,&aa,sizeof(struct a));
    memcpy(str2,&aa,sizeof(struct a));
    for(int i=0;i<10;i++)printf("%2d",str[i]);
    printf("\n");
    for(int i=0;i<10;i++)printf("%2d",str2[i]);

    return 0;
}

以下是o \ p:

98 0 0 0 0 0 0 0 0 0
9888 0 0 0 0 0 0 0 0

以下是生成的警告:

incompatible pointer types passing 'int [10]' to parameter of type 'char *' [-Wincompatible-pointer-types]
incompatible pointer types passing 'struct a *' to parameter of type 'const char *' [-Wincompatible-pointer-types]

3 个答案:

答案 0 :(得分:2)

  

但结构中没有'\ 0'值。

实际上,你确实至少有六个'\0' - s:假设int是32位,9888的高三个字节都是全零。他们会让strncpy停止复制。该函数设计用于固定长度的字符串,因此不应将其与任意struct s一起使用。另一方面,memcpy将复制所有内容。

  

这样做的目的:尝试通过网络发送结构。

如果您希望通过网络发送struct,并希望数据包可移植,请将int转换为发送方的网络订单,然后再转换回硬件订单在接收方。对于32位数字,请使用htonl and ntohl functions

答案 1 :(得分:1)

memcpy复制字节,strcpy复制以空字符结尾的字符串(nul是0字节,0x00,'\ x00')

memcpy始终复制指定的字节数。 strcpy在找到nul时停止复制

答案 2 :(得分:1)

  

但我没有&#39; \ 0&#39;结构中的值。

是的,你这样做。您的整数值有0位,当字节数据被解释为字符时,可以将其解释为'\0'。由于strncpy按字符逐个工作,直到到达终止符#34;这会导致它提前停止。

memcpy复制指定的字节数,始终,这使其工作。在这种情况下更合适。