← 目录 / 第三章 · 输入与输出 / 3.1 cin 与 cout

3.1 cin 与 cout

C++ 风格的输入输出,语法直观、类型自动匹配,是最常用的输入输出方式。本节还将介绍 <iomanip> 提供的精细格式控制。

cin 与 cout

与用户"对话"是程序的基本能力。cin 负责从键盘读取输入,cout 负责向屏幕输出内容,两者都定义在头文件 <iostream> 中,是 C++ 风格的输入输出方式,语法直观、不需要手动指定数据类型。

3.1.1 cin 的工作原理与基础用法

使用 cin 搭配提取运算符 >> 可以从控制台获取键盘输入。语法是:cin >> 变量;>> 这个符号可以理解成一个"箭头",把数据从输入流存入变量里:

⌨️ 键盘输入
cin >>
变量
C++ · cin 输入
1// 读取单个变量
2int age;
3cin >> age; // 等待用户输入一个整数,存入 age
4
5// 同时读取多个变量(用空格或回车分隔)
6int a, b;
7cin >> a >> b; // 输入"3 5"→ a=3, b=5

第 7 行连续写了两个 >>,能这样写是因为 cin >> a 这个表达式本身的结果还是 cin 自己(专业说法是"返回对输入流的引用"),所以可以像接龙一样继续在后面写 >> b。这也是为什么可以一行读入任意多个变量的原因。

⚠️
注意:cin 默认以空白字符(空格、换行、制表符)作为输入的分隔符,并且会自动跳过多余的空白去找下一个有效数据——这就是为什么 a b 之间不管隔了几个空格还是换行,都能正确读到 ab。但反过来,读取字符串时 cin 遇到空格就会停止,要读取含空格的整行内容,需要使用 getline()(详见后续章节)。

3.1.2 cout 的工作原理与基础用法

使用 cout 搭配插入运算符 << 可以将内容输出到控制台。语法是:cout << 输出内容;,方向正好和 cin 相反——数据从变量传出,流向屏幕:

变量 / 字符串
cout <<
🖥️ 屏幕输出
C++ · cout 输出
1cout << "Hello, World"; // 输出字符串
2cout << 123; // 输出数字
3cout << 3.14; // 输出小数
4
5// 用 << 连接多项内容
6int age = 15;
7cout << "我今年" << age << "岁"; // 输出:我今年15岁
8
9// 两种换行方式
10cout << "第一行" << endl; // endl:换行 + 刷新缓冲区(较慢)
11cout << "第二行" << "\n"; // \n:只换行,速度更快 ✓ 推荐

cin 一样,cout << "我今年" 这个表达式的结果也还是 cout 自己,所以才能一路 << 接龙写下去,把字符串和变量混在一起输出,不需要像有些语言那样手动拼接字符串。

endl vs \n:endl 会额外刷新输出缓冲区,速度稍慢;\n 只换行不刷新,速度更快。竞赛编程中大量输出时,推荐用 \n 替代 endl

3.1.3 精度、域宽与填充控制 <iomanip>

使用 cout 输出时,可以通过流控制指令精确控制格式,比如小数保留几位、数字占多少个字符宽度。使用这些功能需引入头文件 <iomanip>

指令 功能说明 示例 输出
setprecision(n) 控制浮点数精度。默认设置有效数字位数;配合 fixed 使用时,设置小数点后位数。持续有效,直到再次修改。 cout<<setprecision(2)<<3.141
cout<<fixed<<setprecision(2)<<3.1415
3.1
3.14
setw(n) 设置下一次输出的字段宽度。宽度不足时用填充字符补齐(默认空格右对齐)。一次性,输出后自动恢复。 cout<<setw(5)<<42 42
setfill(c) 设置 setw 补齐时的填充字符,默认是空格。持续有效,直到再次修改。 cout<<setfill('0')<<setw(5)<<7 00007
⚠️
"一次性"和"持续有效"不要搞混:setw 只管下一个输出对象,用完自动恢复默认宽度;而 setprecisionsetfill 一旦设置就会一直生效,直到你再次修改。如果只想让某一个数字加宽,却忘了 setw 只影响一次,就容易写出"后面所有输出宽度都对不齐"的意外效果——这正是因为你以为它像 setprecision 一样是持续生效的。

3.1.4 进制与格式控制

指令功能示例输出
进制输出
oct 整数以八进制输出 cout<<oct<<10 12
dec 整数以十进制输出(默认) cout<<dec<<10 10
hex 整数以十六进制输出 cout<<hex<<10 a
uppercase 配合 hex,字母大写显示 cout<<hex<<uppercase<<255 FF
缓冲区控制
endl 插入换行符并刷新输出缓冲区 cout<<"Hi"<<endl 换行立即显示
flush 刷新缓冲区,插入换行 cout<<"..."<<flush 立即显示不换行
空白字符处理(cin)
skipws 跳过前导空白字符(默认行为) cin>>skipws>>ch 输入" A"读到A
noskipws 不跳过空白,空格也会被读入 cin>>noskipws>>ch 输入" A"读到空格

3.1.5 对齐与显示格式

指令功能示例输出
对齐方式
left setw 宽度内左对齐,右侧填充 cout<<left<<setw(5)<<42 42
right setw 宽度内右对齐(默认) cout<<right<<setw(5)<<42 42
浮点数格式
scientific 浮点数以科学计数法输出 cout<<scientific<<1234.5 1.234500e+03
fixed 浮点数以定点小数方式输出 cout<<fixed<<1.2 1.200000
showpoint 始终显示小数点,即使小数部分为 0 cout<<showpoint<<10.0 10.0000
符号与前缀
showbase 显示进制前缀(八进制加 0,十六进制加 0x cout<<hex<<showbase<<255 0xff
showpos 正数前显示 + cout<<showpos<<42 +42

3.1.6 常见陷阱与易错点

把本节内容汇总成几条最容易踩坑的规则:

1
cin 读字符串遇空格就停:cin >> str 只能读到第一个空白字符为止,输入"张三 李四"时 str 只会读到"张三"。要读取整行(含空格),必须使用 getline(cin, str)
2
cin 与 getline 混用会漏读:cin >> n 读取数字后,回车符会残留在输入缓冲区里,紧接着的 getline(cin, str) 会先读到这个残留的空行,导致 str 变成空字符串。混用前记得用 cin.ignore() 清掉残留的换行符。
3
setw 是一次性的:setw(n) 只对紧跟着的下一个输出生效,用完就恢复默认宽度。如果想让后面所有数字都保持固定宽度,必须在每次输出前都重新写一次 setw
4
fixed 会改变 setprecision 的含义:不加 fixed 时,setprecision(n) 控制的是"总有效数字位数";一旦加上 fixed,就变成"小数点后的位数"。两种语义混着记很容易算错要保留几位小数。