从 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;
}
}
我知道这是一个简单的问题,但我完全迷路了。 我输入了一个字符串:
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;
}
}