最稳妥方式是std::stoi自动识别前缀或显式指定基数16;传0可识别"0x"/"0X",无前缀时必须传16,否则按十进制解析导致误转换。

用 std::stoi 和 std::to_string 转十六进制字符串为十进制整数
直接把形如 "1a" 或 "0xFF" 的字符串转成 int,最稳妥的方式是让 std::stoi 自动识别进制前缀或显式指定基数。
它会跳过开头空格,识别 "0x"/"0X" 前缀并自动按 16 进制解析;若字符串不含前缀(如 "ff"),必须传入 16 作为第二个参数,否则默认按 10 进制处理——这是最常见的误转换点。
示例:
std::string hex_str = "ff";
int dec = std::stoi(hex_str, nullptr, 16); // → 255
dec = std::stoi("0xFF", nullptr, 0); // → 255,0 表示自动推导
dec = std::stoi("0xFF", nullptr, 10); // → 0,因为 'X' 不是十进制字符,直接失败- 传
0作为基数可启用前缀自动识别,但要求字符串严格符合"0x"或"0X"格式 - 若输入可能含非法字符(如空格、换行、非十六进制字母),
std::stoi会抛std::invalid_argument;建议加try/catch - 超出
int范围时抛std::out_of_range,大数建议用std::stoll+long long
用 std::stringstream 实现双向转换(适合老标准或需格式控制)
当需要兼容 C++98/03,或想统一用流操作符控制输入输出格式(比如固定宽度、补零),std::stringstream 更灵活,但写法略冗长。
立即学习“C++免费学习笔记(深入)”;
关键点:输入时必须设置 std::hex 标志,且对无前缀字符串才有效;输出时同样要设 std::hex,并配合 std::setw 和 std::setfill 补零。
int dec = 255;
std::stringstream ss;
ss << std::hex << dec; // → "ff"
std::string hex_str = ss.str();
<p>ss.clear(); ss.str("");
ss >> std::hex >> dec; // 从 "ff" 读回 255
// 注意:ss << "ff"; ss >> std::hex >> dec; 是可行的,但 ss << "0xff"; 就不行——流不识别前缀-
std::hex只影响数值的进制解析/格式化,不处理前缀;"0xff"会被当作非法输入('0' 后跟 'x' 不被接受) - 输出十六进制默认小写,用
std::uppercase可切大写:ss → <code>"FF" - 流状态(如
failbit)需手动检查,比如if (!(ss >> std::hex >> x)) { /* 错误 */ }
用 sprintf/snprintf 输出十六进制(C 风格,但高效可控)
在嵌入式、性能敏感或需精确控制格式(如固定 4 位、大写、带 0x 前缀)时,C 风格的 snprintf 仍很实用,且避免了流对象开销。
注意:%x 和 %X 分别对应小写和大写十六进制;%04x 表示至少 4 位、不足补零;0x%04x 可拼出带前缀格式。
int dec = 255; char buf[16]; snprintf(buf, sizeof(buf), "%04x", dec); // → "00ff" snprintf(buf, sizeof(buf), "0x%04X", dec); // → "0x00FF"
- 务必确保目标缓冲区足够大,否则溢出未定义;
snprintf返回所需长度,可用于动态分配 -
sprintf不检查缓冲区大小,已基本弃用,生产代码请用snprintf - 不能直接用于宽字符或 Unicode 字符串;如需
std::wstring,得用swprintf或 C++20 的std::format
十六进制字符串转字节序列(比如解析 "A1B2C3" 为 {0xA1, 0xB2, 0xC3})
这不是简单的进制转换,而是「每两个字符一组」转一个字节,常见于网络协议、二进制配置或哈希值解析。C++ 标准库不提供直接支持,需手动拆分+转换。
核心逻辑:检查字符串长度是否为偶数,然后两两截取子串,再用 std::stoi(..., 16) 解析每个字节。
std::string hex = "A1B2C3";
std::vector<uint8_t> bytes;
for (size_t i = 0; i < hex.length(); i += 2) {
std::string byte_str = hex.substr(i, 2);
bytes.push_back(static_cast<uint8_t>(std::stoi(byte_str, nullptr, 16)));
}- 必须确保输入长度为偶数,否则
substr可能越界或解析单字符(如"F"→15,但通常不是预期行为) - 忽略大小写:
std::stoi本身支持大小写混合,无需预处理 - 若输入含空格或分隔符(如
"A1 B2 C3"),需先清洗;可用std::remove_if删除空白字符
这种场景下最容易忽略的是边界校验和错误处理——比如传入 "G1" 会导致 std::stoi 抛异常,而实际协议中更常期望静默失败或返回默认值。


















