std::oct 是仅作用于整型输出的 I/O 操纵符,设置后使后续整数以八进制显示(如 64 输出为 100),不改变值本身、不支持浮点/字符串、不自动加前缀 0;生成字符串需用 std::format(C++20)或 std::stringstream。

用 std::oct 控制输出流进制,但只影响后续整数输出
直接在 std::cout 上设置 std::oct 会切换整个流的整数输出格式为八进制,但它不改变值本身,也不返回字符串。常见误用是以为它能“转换”变量——其实只是格式化显示。
-
std::oct是 I/O 操纵符,需配合使用,例如:std::cout 输出100 - 它对浮点数、字符串无效,只对整型(
int、long等)起作用 - 一旦设置,后续所有整数输出都会按八进制,除非重置为
std::dec或std::hex - 不会自动补前缀
0(C 风格八进制字面量写法),如64输出为100,不是0100
要得到带前缀的八进制字符串?用 std::format(C++20)或 std::stringstream + std::oct
如果目标是生成 std::string(比如存日志、拼接路径、传给 API),不能只靠 std::cout。C++20 起推荐用 std::format;更早版本用 std::stringstream 更可靠。
- C++20:
std::string s = std::format("{:o}", 64);→"100";加前缀写"{:#o}"→"0100" - C++11 及以上:
std::ostringstream oss; oss << std::oct << 64; std::string s = oss.str(); // "100"
- 若需前缀
0:在std::ostringstream中加std::showbase:oss →"0100" - 注意:
std::showbase对std::oct插入0,对std::hex插入0x,对std::dec无效果
手写转换函数?仅当需要控制细节(如固定宽度、符号处理)时才必要
标准库已覆盖绝大多数场景。自己实现容易出错,比如忽略负数、边界值(0)、或效率低下。但若真需要:
- 正数可循环取余:
n % 8,再倒序拼接;0要单独处理 - 负数八进制无统一标准——C++ 输出默认按补码解释(即先转无符号等价形式再输出),如
-1在 32 位下输出很长一串八进制数字;通常业务中八进制只用于非负权限/常量 - 性能上,
std::ostringstream或std::format经过高度优化,比手写快且安全
常见错误:混淆字面量、输入解析和输出格式
很多人卡在“为什么 int x = 0100; 是 64,但 std::cout 却输出 64 而不是 100?”——这是三个不同阶段:
立即学习“C++免费学习笔记(深入)”;
-
0100是源码里的八进制字面量,编译期就转成整数值64存进x -
std::cin >> x默认按十进制读,除非用std::cin >> std::oct >> x std::cout 默认十进制输出,必须显式加std::oct才变八进制显示- 所以“输入八进制”“存储八进制”“输出八进制”三者完全独立,整数变量本身没有进制属性
最易被忽略的是流状态的持久性:std::oct 一旦设置,会影响之后所有同一流上的整数输出,包括第三方库的日志打印——建议用临时流或显式恢复 std::dec,别依赖全局流状态。











