可用hex、dec、oct直接切换cout输出进制,它们是无参流操纵符,作用于后续所有整数输出直至被覆盖,如cout

如何用 hex、dec、oct 切换 cout 输出进制
直接在 cout 流中插入操纵符即可,它们是无参的流操纵符(ios_base& 函数),作用于后续所有整数输出,直到被再次覆盖。
常见写法:
cout << hex << 255; // 输出 ff cout << dec << 42; // 输出 42 cout << oct << 64; // 输出 100
注意:这些操纵符只影响整型(int、long 等),对浮点数、字符串无效;且一旦设置,会持续生效——不是只对当前一个数起作用。
为什么 hex 后输出的字母是小写?如何转大写
默认情况下,hex 输出 a–f 是小写。要改成大写(A–F),需配合 uppercase 操纵符:
立即学习“C++免费学习笔记(深入)”;
cout << hex << uppercase << 255; // 输出 FF cout << hex << nouppercase << 255; // 恢复小写 ff
容易忽略的点:
-
uppercase和nouppercase是全局开关,不仅影响hex,也影响科学计数法中的e(如1.23e+04→1.23E+04) - 它们不会改变进制本身,只是格式修饰,必须和
hex/scientific等一起用才可见效果
如何让某次输出用十六进制,但不干扰后续输出
最稳妥的方式是保存并恢复格式标志,用 ios_base::flags() 或更简洁的 std::hex 配合作用域控制:
推荐做法(局部重置):
int x = 255; cout << "dec: " << dec << x << ", "; cout << "hex: " << hex << x << ", "; cout << "back to dec: " << dec << x;
如果嵌套深或逻辑复杂,可封装成 RAII 风格(C++11 起):
struct BaseGuard {
ios_base& s;
ios_base::fmtflags f;
BaseGuard(ios_base& s) : s(s), f(s.flags()) {}
~BaseGuard() { s.flags(f); }
};
// 使用:
{
BaseGuard g(cout);
cout << hex << 255; // 仅此处 hex
} // 自动恢复之前状态
别依赖“输出完立刻跟 dec”来清理——多线程或函数复用时容易漏掉。
setbase(16) 和 hex 有什么区别
setbase(n) 是带参操纵符,参数为进制基数(8/10/16),但它有个关键限制:只在参数非 0 且为合法进制时生效,否则清空进制标志,退回到 dec。
对比示例:
cout << setbase(16) << 255; // ok → ff cout << setbase(0) << 255; // → 255(自动按字面量推断,但流中无进制标志,等效 dec) cout << setbase(7) << 255; // → 255(非法进制,强制 dec)
所以实际开发中,hex/dec/oct 更安全、语义更明确;setbase 多用于需要动态计算进制的极少数场景,且必须校验输入。
进制切换本身不耗性能,但频繁切换 + 忘记恢复,会在调试时导致输出完全看不懂——尤其日志混着十进制编号和十六进制地址时。











