使用 std::hex、std::showbase、std::setw、std::setfill 和 std::uppercase 可输出带 0x 前缀、补零、大写的十六进制字符串,如 ss << std::hex << std::showbase << std::uppercase << std::setw(4) << std::setfill('0') << 255;

std::stringstream 怎么转十六进制字符串(带前缀)
直接用 std::hex 和 std::showbase 最省事,但默认不补零、不转大写,容易和调试输出混淆。
-
std::hex只影响整数输出格式,对浮点数无效;不自动加0x,得配std::showbase - 要固定宽度(比如 4 位),得用
std::setw(4)+std::setfill('0'),且setw只对下一个输出项生效 - 转大写需
std::uppercase,否则是小写a-f
示例:
std::stringstream ss;
ss << std::hex << std::showbase << std::uppercase << std::setw(4) << std::setfill('0') << 255;
// 结果是 "0X00FF"
sprintf / snprintf 转十六进制要注意什么
比 stream 快,但容易 buffer 溢出或格式错位,尤其在嵌入式或性能敏感场景下仍有人用。
-
%x不带前缀,%#x加0x,但%#X才是大写0X - 必须确保目标缓冲区足够大:4 字节 int 最多要 11 字符(
"0XFFFFFFFF"),别只开 9 -
sprintf不检查长度,推荐用snprintf,返回值是「欲写入长度」,不是是否成功
常见错误现象:snprintf(buf, 4, "%#x", 0x12345) 写不完,buf 变成 "0x1" 还没结束就截断了
立即学习“C++免费学习笔记(深入)”;
std::format(C++20)怎么安全转十六进制
最干净,但要注意编译器支持和格式语法细节,VS 2022 17.5+、GCC 13+ 才完整支持。
- 格式符是
{:#x}(小写)或{:#X}(大写),#表示前缀,0x或0X - 补零用
{:08x},即0填充、宽度 8、小写,注意不能混用#和0填充——{:#08x}是合法的,结果如"0x000000ff" - 不支持运行时格式串(即 format string 不能是变量),所有格式必须在编译期确定
示例:
auto s = std::format("{:#06X}", 255); // "0X00FF"
负数转十六进制字符串会出什么问题
所有标准方法都按补码解释,但人眼容易误读——比如 -1 输出 "ffffffff"(32 位),不是逻辑上的 "-1"。
-
std::stringstream、snprintf、std::format全部把负整数当无符号处理,这是 C/C++ 标准行为 - 如果业务上需要带负号的十六进制(如 "-FF"),得自己判断符号、转绝对值、再拼接,不能依赖内置格式化
- 注意类型:传
int8_t(-1)和int32_t(-1)给std::format("{:x}", x),结果长度不同,前者可能被提升为int导致高位填充
最容易被忽略的是:你看到的 "FFFFFFFE",到底是 -2 还是 4294967294,取决于上下文语义,转换本身不携带符号信息










