英文:
C structure with bits printing in hexadecimal
问题
我已经定义了如下的结构:
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
但没有得到预期的结果。
在64位的Windows系统上,使用0x%04X\n时,我得到了0x3DC18003,而正确的数据应该是0x8003。
我需要知道如何以十六进制打印这个2字节的结构。
英文:
I have defined a structure as below
struct {
UCHAR DSatasetMGMT : 1;
UCHAR AtriburDeallocate : 1;
UCHAR Reserved6 : 6;
UCHAR Reserved7 : 7;
UCHAR DSatasetMGMTComply : 1;
}DatasetMGMTCMDSupport;
It is a 2 byte structure represented in bits. How should I print the whole 2 bytes of structure in hexadecimal. I tried
"DatasetMGMTCMDSupport : 0x%04X\n"
And
0x%04I64X\n
But not getting expected result.
I am getting 0x3DC18003 with 0x%04X\n while the correct data is 0x8003 "
I am using 64 bit windows system.
I need to know how to print 2 byte structure in hexadecimal.
答案1
得分: 2
尝试使用 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 个字节。
宽度 04
指定了最小宽度。由于值需要更多位数,它们会被打印出来。
英文:
Try using 0x%04hx\n
. This tells printf to print out only the two bytes. You can read more about it here: https://en.wikipedia.org/wiki/Printf_format_string#Length_field
In contrast, the I64 in 0x%04I64X\n
tells printf to print out a 64 bit integer, which is 8 bytes, and 0x%04X\n
tells it to print out a default-size integer, which might be 4 bytes on your system.
The width 04
specifies a minimum width. Since the value needs more digits, they are printed.
答案2
得分: 2
从C标准的角度来看,您不能依赖于位字段的特定布局。因此,任何解决方案充其量都具有实现定义的行为。
话虽如此,您可以获得所期望的输出。这个结构适合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个字节的十六进制表示。如果您的系统是小端序的,您应该会看到 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]);
}
这应该给出 8003
。
英文:
From a C Standard point of view, you cannot rely on a particular layout of bit fields. Hence, any solution will at best have implementation-defined behaviour.
That being said, your expected output can be obtained. The structure fits in 2 bytes and if you print sizeof(DatasetMGMTCMDSupport)
it should give the result 2.
The byte representation of DatasetMGMTCMDSupport
can be printed and that is what you were attempting, but since your system has integer size 4, two additional bytes are included. To fix this, the following can be done:
#include <stdint.h>
#include <string.h>
#include <stdio.h>
...
uint16_t a;
memcpy(&a, &DatasetMGMTCMDSupport, sizeof(a));
printf("0x%04X", (unsigned)a);
This copies the 2 bytes of DatasetMGMTCMDSupport
into a 2-byte integer variable and prints the hexadecimal representation of those 2 bytes only. If you are on a little-endian system, you should see 0x8003
.
A more general approach would be to directly print the bytes of DatasetMGMTCMDSupport
:
for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
{
printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[i]);
}
This will most likely print 0380
(notice the byte order: first byte printed first).
To reverse the byte order is straightforward:
for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
{
printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[sizeof(DatasetMGMTCMDSupport)-1-i]);
}
which should give 8003
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论