3 回答
TA贡献1829条经验 获得超13个赞
据我所知,尚无标准功能,但可以通过以下方式轻松实现:
#include <stdio.h>
int main(int argc, char **argv) {
const char hexstring[] = "DEadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
/* WARNING: no sanitization or error-checking whatsoever */
for (size_t count = 0; count < sizeof val/sizeof *val; count++) {
sscanf(pos, "%2hhx", &val[count]);
pos += 2;
}
printf("0x");
for(size_t count = 0; count < sizeof val/sizeof *val; count++)
printf("%02x", val[count]);
printf("\n");
return 0;
}
编辑
正如Al所指出的那样,如果字符串中的十六进制数字为奇数,则必须确保以0开头。例如, 上面的示例"f00f5"将字符串{0xf0, 0x0f, 0x05}错误地评估为字符串,而不是正确的字符串。{0x0f, 0x00, 0xf5}。
稍微修改了示例以解决@MassimoCallegari的评论
TA贡献1936条经验 获得超6个赞
我通过谷歌搜索发现了同样的问题。我不喜欢调用sscanf()或strtol()的想法,因为它感觉像是过分杀了。我编写了一个快速函数,该函数不能验证文本确实是字节流的十六进制表示形式,但是可以处理奇数个十六进制数字:
uint8_t tallymarker_hextobin(const char * str, uint8_t * bytes, size_t blen)
{
uint8_t pos;
uint8_t idx0;
uint8_t idx1;
// mapping of ASCII characters to hex values
const uint8_t hashmap[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // !"#$%&'
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ()*+,-./
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PQRSTUVW
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XYZ[\]^_
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // `abcdefg
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // hijklmno
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pqrstuvw
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xyz{|}~.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ........
};
bzero(bytes, blen);
for (pos = 0; ((pos < (blen*2)) && (pos < strlen(str))); pos += 2)
{
idx0 = (uint8_t)str[pos+0];
idx1 = (uint8_t)str[pos+1];
bytes[pos/2] = (uint8_t)(hashmap[idx0] << 4) | hashmap[idx1];
};
return(0);
}
TA贡献1772条经验 获得超8个赞
对于短字符串,strtol
,strtoll
,并且strtoimax
将工作得很好(请注意,第三个参数是基地在使用处理字符串...它设置为16)。如果您的输入时间长于此,number-of-bits-in-the-longest-integer-type/4
那么您将需要其他答案建议的一种更灵活的方法。
- 3 回答
- 0 关注
- 534 浏览
添加回答
举报