簡體   English   中英

將結構轉換為 C 中的十六進制字符串

[英]Converting a struct to a hex string in C

我有以下結構

typedef struct __attribute__((packed)) word {
    uint16_t value;
    uint8_t flag
} Word;

我想將它轉換為十六進制字符串。 例如,如果value = 0xabcdflag = 0x01我想獲取字符串01abcd

如果我做一些指針雜耍

Word word;
word.value = 0xabcd;
wordk.flag = 0x01;

printf("word: %X\n", *(int *)&word);

我得到了我想要的 output( word: 1ABCD ),但這似乎不安全,當我在查看此處的一些答案后嘗試這樣做時

char ptr[3];
memcpy(ptr, word, 3);
printf("word: %02X%02X%02X\n", ptr[2], ptr[1], ptr[0]);

我得到word: 01FFFFFFABFFFFFFCD ,出於某種原因,前兩個字節被擴展為一個完整的 int

如果您想要的只是 output 兩個結構成員的值,那么亂用指針或類型雙關並沒有真正的好處。 只需單獨打印它們:

printf("word: %02x%04x\n", (unsigned int)word.flag, (unsigned int)word.value);

使用簡單的 sprintf 轉換為字符串:

int main(void)
{
    Word v = { 0xabcd, 0x01 };
    
    char s[10];
    
    sprintf(s, "%02x%04x", v.flag, v.value);
    
    puts(s);
}

我想得到字符串 01abcd

所以你想在小端機器上向后打印結構的二進制表示。 使用sprintf沒有明顯的優勢,除了它實施起來很快而且很臟。

如果你想要一些具有性能的東西,那么手動破解它並不是火箭科學 - 只需逐字節迭代結構並將每個半字節轉換為相應的十六進制字符:

void stringify (const uint8_t* data, size_t size, char* dst)
{
  for(size_t i=0; i<size; i++)
  {
    uint8_t byte = data[size-i-1]; // read starting from the end of the data
    dst[i*2]   = "0123456789ABCDEF"[ byte >> 4  ]; // ms nibble
    dst[i*2+1] = "0123456789ABCDEF"[ byte & 0xF ]; // ls nibble
  }
  dst[size*2] = '\0';
}

這將在小端機器上給出"01ABCD" ,在大端機器上給出“01CDAB "01CDAB"

(可選地向datadst參數添加restrict ,但我懷疑它會提高性能,因為 const 正確性已經在某種程度上阻止了別名。)

可以先在數學上加入他們。

printf("word: %06lx\n", wordk.flag * 0x10000L + word.value);

如果我們在 16 位int機器上,則使用long

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM