在 C 语言中打印十六进制和十进制无符号短整型数值

3
我一直在尝试使用C语言打印无符号短整型(unsigned short int)数值,但没有成功。据我所知,这是一个16位的值,因此我尝试了几种不同的方法来同时打印这2个字节,但只有在逐字节进行时才能正确打印。
请注意,我想以十进制和十六进制格式打印这16位,例如00 01表示1,另一个例子是:00 ff表示255
我有这个结构体:
struct arphdr {
   unsigned short int ar_hrd;
   unsigned short int ar_pro;
   unsigned char ar_hln;
   unsigned char ar_pln;
   unsigned short int ar_op;
   // I'm commenting the following part because I won't need it now
   // for the explanation
   /* unsigned char __ar_sha[ETH_ALEN];
   unsigned char __ar_sip[4];
   unsigned char __ar_tha[ETH_ALEN];
   unsigned char __ar_tip[4]; */ 
};

这个函数:

void print_ARP_msg(struct arphdr arp_hdr) {
   // I need to print the arp_hdr.ar_hrd in both decimal and hex.
   printf("Format HW: %04x\n", arp_hdr.ar_hrd);
   printf("Format Proto: %04x\n", arp_hdr.ar_pro);
   printf("HW Len: %x\n", arp_hdr.ar_hln);
   printf("Proto Len: %x\n", arp_hdr.ar_pln);
   printf("Command: %04x\n", arp_hdr.ar_op);
}

print_ARP_msg函数返回以下内容:

硬件类型格式: 0100

协议类型格式: 0008

硬件地址长度: 6

协议地址长度: 4

命令: 0100

结构体的十六进制值为"00 01 08 00 06 04 00 01",所以我不知道为什么arp_hdr.ar_hrd字段的值是0100。

此外,我编写了一个将结构体以十六进制形式打印的函数,以确保我做得正确。我已经验证了所有字段都被正确赋值。

PS:在提问之前,我意识到它输出了正确的十六进制值但是颠倒了顺序。这可能与小/大端差异有关吗?


1
我不知道你使用的进制是什么,但 0x00ff 不是 16 - EOF
是的,对不起,我正在复制粘贴,把数字弄错了。已经编辑过了。 - lpares12
3个回答

5

这可能与大小端“差异”有关吗?

是的。如果您处理的是通过网络到达的数据包 - 并且您正在打印ARP数据包的字段,那么这正好就是您所做的 - 您可能需要将字段的字节顺序从发送到网络时的字节顺序转换为运行的计算机上的字节顺序。

例如:

printf("Format HW: %04x\n", ntohs(arp_hdr.ar_hrd));

在这种情况下,在大端机器上(SPARC,System / 3x0,z / Architecture,PowerPC / Power ISA运行AIX,PowerPC / Power ISA运行Mac OS X,可能 PowerPC / Power ISA 运行Linux等)可以省略对ntohs()函数的调用,但是在小端机器上(包括x86处理器,包括x86-64处理器,可能大多数ARM等)无法省略它。

你可以在两种类型的处理器上都使用它。


谢谢!我能够使用格式说明符%hu和函数ntohs()以十进制打印值。 - lpares12

2
结构体的十六进制值为“00 01 08 00 06 04 00 01”,所以我不知道为什么arp_hdr.ar_hrd值返回给我0100。
看起来你的平台使用小端系统。
在内存中似乎是“00 01”,但被解释为“01 x 2^8 + 00”。换句话说,该数字的十六进制表示为“0100”。

2

ARP数据包,就像所有互联网协议数据包一样,以"网络顺序"传输,即大端字节序。客户端必须使用例如 ntohs (网络到主机短整数)将网络顺序转换为机器的本地字节顺序,而使用 htons 反之。

有关详细信息,请参见 man byteorder


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接