从 uint8_t 到十六进制字符串数组?

From uint8_t to hex string array?

我知道这是一个简单的问题,但我完全迷路了。 我输入了一个字符串:

input: 220209

我要:

output: uint8_t myarr[8]={0x22,0x02,0x09,0x00, 0x00, 0x00,0x00,0x00}

所以 myarr 的维度始终为 8,如果我有一个较低的输入字符串,我必须用 0x00 来完成。有人可以给我任何想法吗? 抱歉打扰您,我们将不胜感激。

此致

希望对你有用

memset(myarr, 0, 8);
int szLen = strlen(szInput);
for(int i = 0; i < szLen / 2; i++) {
   uint8_t high = toupper(szInput[i*2]);
   uint8_t low = toupper(szInput[i*2 + 1]);

   if(high >= '0' && high <= '9')
       high = high - '0';
   if(low >= '0' && low <= '9')
       low = low - '0';
   if(high >= 'A' && high <= 'F')
       high = high - 'A' + 10;
   if(low >= 'A' && low <= 'F')
       low = low - 'A' + 10;
   myarr[i] = (high << 4) | low; // bit operation is faster than arithmetic
}

使用 strtol() 一次转换 2 个字符,显式使用 base 16 可以很容易:

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

// Assume s has an even number of hexdigit chars (at most 16) followed by a nul
void convert(const char *s, uint8_t out[static 8]) {
  int i = 0;
  // Handle 2 chars at a time
  while (*s) {
    char byte[3] = { *s, *(s + 1), 0 };
    out[i++] = strtol(byte, NULL, 16);
    s += 2;
  }
  // Fill the rest of the array with nuls
  for (; i < 8; i += 1) {
    out[i] = 0;
  }
}

int main(void)
{
  const char *input = "220209";
  uint8_t myarr[8];

  convert(input, myarr);

  // Pretty-print the array using hex values
  fputs("uint8_t myarr[8] = { ", stdout);
  for (int i = 0; i < 8; i += 1) {
    printf("0x%02" PRIx8, myarr[i]);
    if (i < 7) {
      fputs(", ", stdout);
    }
  }
  puts(" };");

  return 0;
}

另一种选择是使用sscanf()一次解析两个字符:

void convert(const char *s, uint8_t out[8]) 
{
    memset(out, 0, 8);
    while (sscanf(s, "%2"SCNx8, out++) == 1) {
        s += 2;
    }
}

第一行利用64位算法将8个字节设置为0。然后我们扫描字符串 s 中的两个字符,从十六进制 ASCII 表示中读取 uint8_t 类型的整数。如果读取成功,我们将移动到下两个字符。

它看起来像 code golf 提交,但它很好,因为没有被复制。

另一个版本可能是:

void convert(const char *s, uint8_t out[8])
{
    static char tbl[] = {
        0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
        0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, 
        0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
        0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0,
        0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
        0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
        0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
        0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
    };
    
    memset(out, 0, 8);
    while (*s) {
        *out++ = tbl[s[0]] * 16 + tbl[s[1]];
        s += 2;
    }
}