如何将十六进制字符串转换为对应十六进制值的缓冲区?
问题
给定十六进制字符串:
char *hexa_string= "ab010210000000000000000000000a0040890080006400950000920050050900300c3b811504a0ff2c8cf5e91740e466b219c2a3318ce80b66e1c43ba65ade66";
需要将其转换为缓冲区,使得缓冲区每个元素对应字符串中的两位十六进制数字。
尝试了以下代码,但用printf输出缓冲区时看不到内容,期望得到类似hexa_buffer[0] = 0xab、hexa_buffer[1] = 0x01这样的结果:
char *hexa_string= "ab010210000000000000000000000a0040890080006400950000920050050900300c3b811504a0ff2c8cf5e91740e466b219c2a3318ce80b66e1c43ba65ade66"; int hexa_string_size = strlen(hexa_string); uint8_t hexa_buffer[64]; char *temp = hexa_string; for(int i = 0; i < hexa_string_size; i++){ sscanf(temp, "%02hhx", &hexa_buffer[i]); temp += 2; }
解决方法
你的代码核心问题是循环条件错误:字符串长度是两位十六进制数的总字符数,每两个字符对应一个uint8_t元素,所以循环次数应该是hexa_string_size / 2,而不是遍历整个字符串长度。原代码中i < hexa_string_size会导致循环执行过多次数,超出缓冲区hexa_buffer的容量(你的字符串长度是128,对应64个字节,原循环会跑128次,直接越界),引发未定义行为。
修正后的代码如下:
#include <stdio.h> #include <string.h> #include <stdint.h> int main() { char *hexa_string= "ab010210000000000000000000000a0040890080006400950000920050050900300c3b811504a0ff2c8cf5e91740e466b219c2a3318ce80b66e1c43ba65ade66"; int hexa_string_size = strlen(hexa_string); // 确保缓冲区大小足够,这里字符串长度128,对应64个uint8_t uint8_t hexa_buffer[hexa_string_size / 2]; char *temp = hexa_string; // 循环次数是字符数的一半 for(int i = 0; i < hexa_string_size / 2; i++){ // %02hhx 用于读取两位十六进制到uint8_t变量 sscanf(temp, "%02hhx", &hexa_buffer[i]); temp += 2; } // 正确输出缓冲区内容 for(int i = 0; i < hexa_string_size / 2; i++){ printf("hexa_buffer[%d] = 0x%02x\n", i, hexa_buffer[i]); } return 0; }
关键点说明
- 循环次数修正:
hexa_string_size是字符串的字符总数,每两个字符转一个字节,所以循环次数必须是hexa_string_size / 2,避免缓冲区越界。 - 输出格式:用
printf输出uint8_t时,要使用%02x格式符(会自动将无符号字节转为十六进制,补前导零),如果直接用%c会把字节当作ASCII字符输出,很多不可见字符会导致看不到内容,这也是你之前输出无内容的原因之一。 - 缓冲区容量:可以直接用
hexa_string_size / 2定义缓冲区大小,保证足够容纳转换后的所有字节,避免固定大小可能出现的不匹配问题。
内容的提问来源于stack exchange,提问作者user123454321
相关产品推荐
相关产品推荐

