You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Arduino环境下将十六进制值字符串还原为原始字节数组的方法

Arduino十六进制字符串转字节数组优化方案

你原有写法的核心问题是重复调用sscanf且每次从字符串起始位置扫描,执行效率低、代码冗余,以下提供两种更优的实现方案:

方案1:精简sscanf实现(易维护)

利用%n格式符获取每次解析消耗的字符数,通过循环读取即可实现批量转换,无需重复写多段相似逻辑:

char addr3[47] = "0x28, 0xB6, 0x4C, 0x4E, 0x0D, 0x00, 0x00, 0x86";
byte addr2[8];
char* cur_ptr = addr3;
int parse_offset;

for (uint8_t i = 0; i < 8; i++) {
    // %x读取十六进制数,%n存储本次解析消耗的字符数
    sscanf(cur_ptr, "%x%n", (int*)&addr2[i], &parse_offset);
    cur_ptr += parse_offset; // 指针偏移到下一个十六进制数起始位置
}

优势:

  • 代码量仅为原有写法的1/4,可扩展性强,修改数组长度只需调整循环次数
  • 减少了7次重复的字符串扫描,执行效率更高

方案2:无库轻量实现(低资源占用)

如果使用的是Uno、Nano这类Flash资源紧张的8位Arduino板,可避开占用空间较大的sscanf,手动实现十六进制解析,Flash占用可降低2KB以上:

char addr3[47] = "0x28, 0xB6, 0x4C, 0x4E, 0x0D, 0x00, 0x00, 0x86";
byte addr2[8];
uint8_t arr_idx = 0;
uint8_t cur_byte = 0;
bool parsing_num = false;

for (char* p = addr3; *p != '\0' && arr_idx < 8; p++) {
    if (isxdigit(*p)) { // 匹配十六进制字符
        cur_byte = cur_byte * 16 + ( (*p <= '9') ? (*p - '0') : (tolower(*p) - 'a' + 10) );
        parsing_num = true;
    } else if (parsing_num) { // 单字节解析完成
        addr2[arr_idx++] = cur_byte;
        cur_byte = 0;
        parsing_num = false;
    }
}
// 兼容最后一个字节后无分隔符的场景
if (parsing_num && arr_idx < 8) {
    addr2[arr_idx++] = cur_byte;
}

补充说明

你之前运行结果显示为28B64C4ED0086属于打印显示问题,不是数组存储错误:你打印时没有为0x00这类值输出前导零,实际数组中存储的数值是符合预期的。

内容的提问来源于stack exchange,提问作者SammyG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:18:03