cout 默认的输出很"素":小数位不定、不对齐、不补零。想排版就得请出 <iomanip> 里的操纵符:fixed + setprecision(2) 保留两位小数(金额必备)、setw(n) 定字段宽度(⚠ 只对下一个输出有效)、setfill('0') 补零、left / right 左右对齐、hex / oct / dec 切换进制、boolalpha 把布尔显示成文字。本篇还把教材的实例 03、04 收进来:用它们做一个对齐的"价格表",并认识 C 语言传下来的 printf。
一、请先 #include <iomanip>
#include <iostream>
#include <iomanip> // setw / setprecision / setfill 都在这里
using namespace std;
忘了这个头文件,setw 这些名字就"未声明"——报错时先想它。
二、最常用的六个操纵符
| 操纵符 | 作用 | 例子 | 输出 |
|---|---|---|---|
setprecision(n) |
设置精度(见下节说明) | cout << setprecision(3) << 3.14159 |
3.14 |
fixed |
定点表示 → 精度变成"小数位数" | cout << fixed << setprecision(2) << 12.5 |
12.50 |
setw(n) |
字段最小宽度(不够则补空格) | cout << setw(6) << 42 |
42 |
setfill(c) |
用什么字符填充(配合 setw) |
cout << setfill('0') << setw(4) << 7 |
0007 |
left / right |
左对齐 / 右对齐(默认右对齐) | cout << left << setw(6) << "ab" |
ab |
hex / oct / dec |
输出进制 | cout << hex << 255 |
ff |
boolalpha |
布尔显示成文字 | cout << boolalpha << true |
true |
三、两个必须记住的细节(考试与实战都爱考)
细节一:setprecision 加不加 fixed,意思完全不同
cout << setprecision(2) << 3.14159 << endl; // 3.1 ← 2 位【有效数字】
cout << fixed << setprecision(2) << 3.14159 << endl; // 3.14 ← 2 位【小数】
| 写法 | 精度的含义 | 什么时候用 |
|---|---|---|
setprecision(n) |
有效数字位数 | 科学计算 |
fixed << setprecision(n) |
小数点后位数 | 金额、成绩、尺寸——日常最常用 |
要"保留两位小数",永远记得配上 fixed。
细节二:其他设置是"粘"的,setw 是"一次性"的
cout << fixed << setprecision(2); // 这两句一直有效,后面所有输出都受影响
cout << setw(8) << 1.5 << endl; // 8 宽
cout << 2.5 << endl; // ← setw 已经失效,按默认宽度输出
为什么 setw 特殊:宽度总是"逐个字段"指定的,让所有人每次都要重设。这是新手最常见的困惑:明明设了 setw(8),第二行就没对齐了——要每行都写一次。
四、实例 03:做一个对齐的价格表
新建 format.cpp:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << left << setw(10) << "商品"
<< right << setw(10) << "单价"
<< setw(8) << "数量"
<< setw(12) << "小计" << endl;
cout << fixed << setprecision(2); // 从这里开始,所有小数都是两位
cout << left << setw(10) << "苹果"
<< right << setw(10) << 12.5
<< setw(8) << 3
<< setw(12) << 12.5 * 3 << endl;
cout << left << setw(10) << "香蕉"
<< right << setw(10) << 8.0
<< setw(8) << 5
<< setw(12) << 8.0 * 5 << endl;
// 用 setfill 补零做一个"编号"
cout << "编号:" << setfill('0') << setw(6) << 42 << endl; // 000042
return 0;
}
看到什么算成功:
商品 单价 数量 小计
苹果 12.50 3 37.50
香蕉 8.00 5 40.00
编号:000042
这就是表格输出的基本套路:表头与数据行用同样的 setw 宽度 + 同样的对齐方式,自然就能对齐(注意:中文宽度与英文不同,所以中文列的对齐会有偏差,这属于"字符宽度"问题,不是 setw 的错)。
五、实例 04:用 printf 输出
C 语言传来的老手艺,需要 #include <cstdio>:
#include <cstdio>
printf("%-6s %8.2f\n", "苹果", 12.5);
格式符速查:
| 格式符 | 含义 |
|---|---|
%d |
整数 |
%f |
浮点(默认 6 位小数) |
%.2f |
保留两位小数 |
%c |
字符 |
%s |
字符串 |
%5d |
宽度 5、右对齐 |
%-5d |
宽度 5、左对齐 |
%05d |
宽度 5、补 0 |
printf vs cout 怎么选:
cout |
printf |
|
|---|---|---|
| 类型安全 | 好(不用写格式符) | 差(%d 配错类型结果会乱) |
| 排版方便度 | 一般(要写一串操纵符) | 好(一个格式串搞定) |
| 可扩展 | 能输出自定义类型 | 不能 |
| 建议 | 默认用它 | 老代码要看懂;需要紧凑排版时可以混用 |
混用没问题(两者都往同一个屏幕写),只是别指望顺序完全符合直觉(缓冲机制不同的缘故)。
六、动手 Demo:把"实例 03 + 实例 04"对照着跑
在同一个 format.cpp 里加:
printf("%-10s%10.2f%8d%12.2f\n", "橘子", 6.5, 4, 6.5 * 4);
看到什么算成功:这一行的排版和上面 cout 那几行基本一致——同样的需求,两套工具都能做。
30 秒实验:把这一行里的 %-10s 改成 %10s(去掉减号),看"橘子"是从左边顶格还是右边顶格——这就把"左对齐/右对齐"刻进手感里了。
七、常见误区
- "
setprecision(2)就是保留两位小数"——不一定!不加fixed时它是"2 位有效数字"(3.14159→3.1)。要小数位就必须配fixed - "
setw设一次就一直有效"——只对下一个输出有效。每行都要重写 - "忘了
#include <iomanip>也能用"——不能。setw、setprecision、setfill都在<iomanip>里 - "中文表格也能用
setw完美对齐"——不行。一个汉字占两个英文字符的显示宽度,但setw数的是"字节/字符数",所以中文列会歪。要精细对齐得手工补空格(这是控制台输出的通病,不是 C++ 的缺陷)
自测四问(点开对答案)
1. 想输出"保留两位小数"该怎么写?——`cout << fixed << setprecision(2) << 值;`(**必须加 `fixed`**)。 2. `setw(8)` 的作用范围?——**只对紧接着的那一个输出有效**,下一项就恢复默认。 3. 怎么把 42 输出成 `000042`?——`cout << setfill('0') << setw(6) << 42;` 4. 用 `printf` 输出保留两位小数的浮点数怎么写?——`printf("%.2f", x);`(`%8.2f` 表示宽度 8)。- ☑ 小结