🔷 第二章 C++语言基础
📄 一句话概括

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(去掉减号),看"橘子"是从左边顶格还是右边顶格——这就把"左对齐/右对齐"刻进手感里了。

七、常见误区

  1. "setprecision(2) 就是保留两位小数"——不一定!不加 fixed 时它是"2 位有效数字"(3.14159 → 3.1)。要小数位就必须配 fixed
  2. "setw 设一次就一直有效"——只对下一个输出有效。每行都要重写
  3. "忘了 #include <iomanip> 也能用"——不能。setw、setprecision、setfill 都在 <iomanip> 里
  4. "中文表格也能用 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)。

相关笔记