我有下面的代码。我正在尝试将结构复制到字符串。我想了解为什么输出在 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)由基思·汤普森建议
下面是生成的警告。
incompatible pointer types passing 'struct a *' to parameter of type 'const char *' [-Wincompatible-pointer-types]
2)我稍微修改了代码以使用 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;
}
下面是 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]
但我的结构中没有"\0"值。
实际上,您确实至少有六个 ' '
-s:假设 int
是 32 位,则 98
和 88
的前三个字节都是零。他们会让strncpy
停止复制。该函数是为固定长度的字符串设计的,因此不应将其与任意struct
一起使用。 另一方面,memcpy
会复制一切。
这样做的目的:尝试通过网络发送结构。
如果要通过网络发送struct
,并且希望数据包是可移植的,请将发送端的两种int
转换为网络顺序,并在接收端转换回硬件顺序。对于 32 位数字,请使用 htonl
和 ntohl
函数。
memcpy 复制字节,strcpy 复制以 nul 结尾的字符串(NUL 是 0 字节,0x00,'\x00')
Memcpy 始终复制指定数量的字节。 strcpy 在找到 nul
但是我在结构中没有"\0"值。
是的,你愿意。 整数值具有 0 位,当字节数据解释为字符时,可以将其解释为' '
。 由于strncpy
"逐个字符地工作,直到到达终结者",这会导致它提前停止。
memcpy
始终复制指定数量的字节,使其正常工作。 在这种情况下更合适。