以十六进制打印位的C结构

mctunoxg  于 2023-02-18  发布在  其他
关注(0)|答案(2)|浏览(167)

我已经定义了一个结构如下

struct {
        UCHAR   DSatasetMGMT : 1;
        UCHAR   AtriburDeallocate : 1;
        UCHAR   Reserved6 : 6;
        UCHAR   Reserved7 : 7;
        UCHAR   DSatasetMGMTComply : 1;
    }DatasetMGMTCMDSupport;

这是一个2字节的结构表示位。我应该如何打印整个2字节的结构在十六进制。我试过

"DatasetMGMTCMDSupport                          :   0x%04X\n"

还有

0x%04I64X\n

但未达到预期效果。
我得到的是带有0x%04X\n的0x3DC18003,而正确的数据是0x8003“
我使用的是64位windows系统。
我需要知道如何打印十六进制的2字节结构。

huwehgph

huwehgph1#

尝试使用0x%04hx\n,它告诉printf只输出两个字节,你可以在这里阅读更多信息:https://en.wikipedia.org/wiki/Printf_format_string#Length_field
相比之下,0x%04I64X\n中的I64告诉printf打印出一个64位整数,也就是8个字节,而0x%04X\n告诉它打印出一个默认大小的整数,在您的系统上可能是4个字节。
width 04指定了一个 minimum 宽度。由于该值需要更多的位数,因此会打印出来。

jum4pzuy

jum4pzuy2#

从C标准的Angular 来看,你不能依赖于位域的特定布局,因此,任何解决方案最多只能有实现定义的行为。
也就是说,可以得到预期的输出,该结构适合2个字节,如果打印sizeof(DatasetMGMTCMDSupport),结果应该给予2。
DatasetMGMTCMDSupport的字节表示可以打印出来,这也是您所尝试的,但由于您的系统具有整数大小4,因此包含了两个额外的字节。要解决此问题,可以执行以下操作:

#include <stdint.h>
#include <string.h>
#include <stdio.h>
...
    uint16_t a;
    memcpy(&a, &DatasetMGMTCMDSupport, sizeof(a));
    printf("0x%04X", (unsigned)a);

这将DatasetMGMTCMDSupport的2个字节复制到一个2字节的整型变量中,并只打印这2个字节的十六进制表示。如果你使用的是little-endian系统,你应该看到0x8003
更通用的方法是直接打印DatasetMGMTCMDSupport的字节:

for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
    {
        printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[i]);
    }

这很可能会打印0380(注意字节顺序:首先打印的第一字节)。
反转字节顺序非常简单:

for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
    {
        printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[sizeof(DatasetMGMTCMDSupport)-1-i]);
    }

这应该给予X1 M6 N1 X。

相关问题