std::hex 仅切换流的整数进制标志,不补零、不加前缀、不控宽;需配合 std::setw、std::setfill 和手动添加 "0x" 才能输出如 0x00ff 的格式。

直接用 std::hex 不会自动补零、不控制宽度、不保留前缀,输出结果常不符合预期——它只是切换流的整数进制标志,不是“格式化函数”。
std::hex 只是流状态标记,不影响字符串内容本身
std::hex 修改的是 std::ostream 对后续整数的默认解析方式,不改变已有变量值,也不生成带 0x 前缀的字符串。它和 std::dec、std::oct 一样,属于流操纵器(manipulator),仅作用于流对象的状态位。
- 连续写入多个整数时,
std::hex会持续生效,直到被std::dec等覆盖 - 它对浮点数、字符串、自定义类型无效
- 不会自动补零,
int x = 5;输出就是5,不是05或0x05
输出带 0x 前缀和固定宽度的十六进制需组合使用
要得到类似 0x00ff 这样的输出,必须手动加前缀,并用 std::setw 和 std::setfill 控制宽度与填充字符。注意:这些设置只对下一个输出项生效,需重复设置或重置。
int val = 255;
std::cout << "0x" << std::hex << std::setw(4) << std::setfill('0') << val << '\n';
// 输出:0x00ff
-
std::hex必须放在std::setw和std::setfill之前,否则进制不生效 -
std::setw只影响紧随其后的单个输出项,下一次输出需重新调用 -
std::setfill('0')会持续生效,直到再次调用std::setfill - 若要恢复十进制,显式写
std::dec,别依赖隐式行为
避免流状态污染:优先用 std::format(C++20)或 stringstream 隔离
全局修改 std::cout 的状态容易引发难以追踪的 bug,尤其在多线程或大型项目中。更安全的做法是用 std::stringstream 构造局部格式化,或直接用 std::format(C++20)。
立即学习“C++免费学习笔记(深入)”;
// C++20 推荐(无状态副作用)
std::string s = std::format("0x{:04x}", 255); // "0x00ff"
// 兼容旧标准:用 stringstream
std::stringstream ss;
ss << "0x" << std::hex << std::setw(4) << std::setfill('0') << 255;
std::string t = ss.str(); // "0x00ff"
-
std::format是值语义,无流状态,线程安全,且支持{:04x}这类 Python 风格格式说明符 - 用
std::stringstream时,每个实例独立,不会干扰其他流 - 不要在函数内长期修改
std::cout的 fill/width,除非你明确负责还原
真正麻烦的不是怎么输出十六进制,而是忘记流状态是持久的、跨输出项的——一个没重置的 std::hex 可能让几行之后的 std::cout 突然变成 64。要么全程用 std::format,要么每次操作后立刻配对恢复(比如 std::dec),别指望“后面没人用 cout”。











