跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C++如何将16进制字符串转为字节数组 _ 字符位移运算技巧【干货】

使用 std::stoi 转换单字节十六进制字符对时,须显式指定进制为 16(如 std::stoi(s, nullptr, 16)),否则按十进制解析会抛出异常;输入长度应为偶数,大小写不敏感,但含非法字符将静默截断,建议改用 std::stoul 配合异常处理。 std::stoi 转换单字节十六进制字符对时要注意什么 直接用
std::stoi
解析两位十六进制字符串(如
"a3"
)是可行的,但必须显式指定进制为 16,否则默认按十进制解析,
"a3"
会抛出
std::invalid_argument
异常。 必须传入
0
作为基底参数(
std::stoi(s, nullptr, 16)
),不能省略或写成
10
输入字符串长度必须为偶数,否则最后一位无法配对;建议提前检查
s.length() % 2 != 0
并报错或补前导零
std::stoi
对大小写不敏感,
"FF"
、
"ff"
、
"Ff"
都能正确转为 255 若字符串含空格或非十六进制字符(如
'g'
),会截断到首个非法字符位置,易造成静默错误——应改用
std::stoul
+ 异常捕获更稳妥 手动字符位移拼接字节比库函数更快吗 对短字符串((nibble1 )通常比
std::stoi
快 2–3 倍,因为避免了异常机制、字符串查找和内存分配开销。但前提是:你得先安全地把字符转成 0–15 的数值。 小写字母
'a'
–
'f'
要减
'a' - 10
,大写同理减
'A' - 10
;直接减
'a'
会得到负数 推荐用查表法预生成 256 元素的
char_to_nibble
数组,索引为
unsigned char
,值为 0–15 或 -1(非法) 位移操作本身无风险,但注意:两个
char
拼成一个
uint8_t
时,务必先转成无符号类型再移位,否则
char
是有符号的,
'f'
(102)没问题,但若误用负值会触发未定义行为 std::vector 接收结果时如何避免重复分配 目标容器大小在解析前就已确定:
output.size() == input.length() / 2
。不预留空间会导致多次
realloc
,尤其在嵌入式或高频调用场景下明显拖慢性能。 构造时直接指定容量:
std::vector bytes; bytes.reserve(input.length() / 2);
不要用
bytes.push_back()
循环追加,改用索引赋值:
bytes[i] = (hi
如果输入为空字符串,
length()/2
为 0,
reserve(0)
安全,无需额外判断 返回前可调用
bytes.shrink_to_fit()
,但仅当后续长期持有该 vector 且内存敏感时才值得做 遇到 "0x" 前缀或空格该怎么处理 真实数据常带
"0x"
(如
"0xFFA3"
)或空格分隔(如
"FF A3 00"
),标准转换函数不自动跳过这些。硬编码跳过前缀或全局替换空格都容易出错。 C知道 CSDN推出的一款AI技术问答工具 下载 立即学习 “ C++免费学习笔记(深入) ”; 检测开头是否为
"0x"
或
"0X"
:用
input.compare(0, 2, "0x") == 0
,然后从索引 2 开始解析 处理空格分隔:不建议用
std::stringstream
(开销大),而应遍历原字符串,跳过空白,每遇到两个非空字符就解析一组 更鲁棒的做法是先清洗:用
std::remove_copy_if
把所有空白和
'x'
/
'X'
过滤掉,再统一按偶数长度处理——但注意别把
'x'
从中间字段里误删(如
"ABxCD"
不合法,本就不该出现) 真正难的不是转换逻辑,而是决定“非法输入”算报错、跳过,还是容错修复——这取决于你的协议层约定,代码里得明确写死策略,别留给调用方猜。

相关文章