2014-12-01 20 views
3

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

#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)由基思·汤普森

建议下面是生成警告。

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

2)I修改代码中的位,以使用int数组:

(把此供参考我明白,在这种情况下,memcpy的拷贝结构体中的前两个元素的变量。阵列的大小是足够的结构变量)

#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; 
} 

下面是邻\号码:

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] 
+0

您的结构不是字符串。 'strncpy'对字符串进行操作。这个电话甚至不应该编译;你至少应该得到一个'struct a *'参数传递给'strncpy'的警告,它需要'char *'。即使对于字符串,通常也应该避免使用“strncpy”。 [见我在这里主题的咆哮](http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html)。 – 2014-12-01 20:08:26

+0

它的确发出了警告。 – mayur 2014-12-02 10:49:19

+0

请更新您的问题以显示确切的警告;这是非常重要的信息。 – 2014-12-02 14:54:12

回答

2

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

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

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

如果你想在网络的struct送过来,和你想的包是便携式的,都转换int s到网络上的发送方订单,并返回到硬件以便在接收端。对于32位数字,请使用htonl and ntohl functions

+0

谢谢,错过了'\ 0'等于0.strcpy会停在0。 – mayur 2014-12-02 06:53:59

1

的memcpy拷贝字节,strcpy的副本空终止字符串(NUL是0字节,0×00, '\ X00')

的memcpy总是拷贝指定的字节数。 strcpy停止复制,当它发现nul

1

但我没有在结构中的'\ 0'值。

是的,你这样做。您的整数值有0位,当字节数据被解释为字符时,可将其解释为'\0'。由于strncpy“按字符直到达到终止符”起作用,这导致它提前停止。

memcpy复制指定的字节数,总是,这使它工作。在这种情况下更合适。

+0

谢谢,错过了'\ 0'等于0 – mayur 2014-12-02 06:54:54