简体   繁体   English

从结构位域以十六进制打印完整的uint32_t

[英]Print full uint32_t in hex from struct bitfield

I have a structure like below: 我的结构如下:

struct myCoolStuff{
    uint32_t stuff1 :  4;
    uint32_t stuff2 :  4;
    uint32_t stuff3 : 24;
    uint32_t differentField;
}

How can I combine these fields into a hex format for printing to the screen or writing out to a file? 如何将这些字段组合成十六进制格式以打印到屏幕或写出文件? Thank you. 谢谢。

struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233, .differentField=99};

printf("my combined stuff is: %x\n", <combined stuff>);
printf("My full field is: %x\n", data.differentField);

Expected Output: 
my combined stuff is: 0xFF66112233 
My different field is: 99

First, you can't get 0xFF out of 0xFF after you put it in a 4-bit variable. 首先,你不能得到0xFF0xFF ,你把它放在一个4位的变量之后。 0xFF takes 8 bits. 0xFF占用8位。 Same for 0x66 . 0x66相同。

As for reinterpretting the bitfields as a single integer, you could, in a very nonportable fashion (there's big-endian/little-endian issues and the possibility of padding bits) use a union . 至于将位域重新解释为单个整数,则可以以非常不方便的方式(存在大尾数/小尾数问题以及填充位的可能性)使用并union

( This: ( 这个:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

struct myCoolStuff{
    union{
        struct {
        uint32_t stuff1 :  4;
        uint32_t stuff2 :  4;
        uint32_t stuff3 : 24;
        };
        uint32_t fullField;
    };
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};

int main()
{
    printf("My full field is: %" PRIX32 "\n", data.fullField);
}

prints 1122336F on my x86_64. 在我的x86_64上打印1122336F )

To do it portably you can simply take the bitfields and put them together manually: 要做到这一点可移植 ,你可以简单地把位域和手动把它们放在一起:

This: 这个:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

struct myCoolStuff{
        uint32_t stuff1 :  4;
        uint32_t stuff2 :  4;
        uint32_t stuff3 : 24;
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};

int main()
{
    uint32_t fullfield = data.stuff1 << 28 | data.stuff2 << 24 | data.stuff3;
    printf("My full field is: %" PRIX32 "\n", fullfield);
}

should print F6112233 anywhere where it compiles ( uint32_t isn't guaranteed to exist (although on POSIX platforms it will); uint_least32_t would've been more portable.) 应该在可编译的任何地方打印F6112233 (不保证uint32_t存在(尽管在POSIX平台上会存在); uint_least32_t会更易于移植。)

Be careful to make sure data.stuff1 has enough bits to be shiftable by 28 . 注意确保data.stuff1有足够的位可移动28 Yours does because it's typed uint32_t , but it would be safer to do it eg, with (data.stuff1 + 0UL)<<28 or (data.stuff1 + UINT32_C(0))<<28 and same for the second shift. 您这样做是因为键入uint32_t ,但是这样做会更安全,例如(data.stuff1 + 0UL)<<28(data.stuff1 + UINT32_C(0))<<28 ,第二个移位相同。

Add a union inside of this struct that you can use to reinterpret the fields. 在此结构内添加一个并集,可用于重新解释字段。

struct myCoolStuff{
    union {
        struct {
            uint32_t stuff1 :  4;
            uint32_t stuff2 :  4;
            uint32_t stuff3 : 24;
        };
        uint32_t stuff;
    }
    uint32_t fullField;
};

...

printf("my combined stuff is: %x\n", data.stuff);

Multiply (using at least uint32_t math) and then print using the matching specifier. 相乘(至少使用uint32_t数学),然后使用匹配的说明符进行打印。

#include <inttypes.h>

struct myCoolStuff{
    uint32_t stuff1 :  4;
    uint32_t stuff2 :  4;
    uint32_t stuff3 : 24;
    uint32_t differentField;
}

uint32_t combined stuff = ((uint32_t) data.stuff1 << (4 + 24)) | 
    ((uint32_t) data.stuff2 <<  24) |  data.stuff3;

printf("my combined stuff is: 0x%" PRIX32 "\n", combined stuff);
printf("My full field is: %x\n", data.differentField);

Maybe something like this will help : 也许这样的事情会有所帮助:

unsigned char *ptr = (unsigned char *)&data; // store start address
int size = sizeof(myCoolStuff); // get size of struct in bytes
while(size--) // for each byte
{
    unsigned char c = *ptr++; // get byte value
    printf(" %x ", (unsigned)c); // print byte value
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM