C++ 风格的输入输出,语法直观、类型自动匹配,是最常用的输入输出方式。本节还将介绍 <iomanip> 提供的精细格式控制。
3.1
与用户"对话"是程序的基本能力。cin 负责从键盘读取输入,cout 负责向屏幕输出内容,两者都定义在头文件 <iostream> 中,是 C++ 风格的输入输出方式,语法直观、不需要手动指定数据类型。
使用 cin 搭配提取运算符 >> 可以从控制台获取键盘输入。语法是:cin >> 变量;。>> 这个符号可以理解成一个"箭头",把数据从输入流存入变量里:
| 1 | // 读取单个变量 |
| 2 | int age; |
| 3 | cin >> age; // 等待用户输入一个整数,存入 age |
| 4 | |
| 5 | // 同时读取多个变量(用空格或回车分隔) |
| 6 | int a, b; |
| 7 | cin >> a >> b; // 输入"3 5"→ a=3, b=5 |
第 7 行连续写了两个 >>,能这样写是因为 cin >> a 这个表达式本身的结果还是 cin 自己(专业说法是"返回对输入流的引用"),所以可以像接龙一样继续在后面写 >> b。这也是为什么可以一行读入任意多个变量的原因。
cin 默认以空白字符(空格、换行、制表符)作为输入的分隔符,并且会自动跳过多余的空白去找下一个有效数据——这就是为什么 a b 之间不管隔了几个空格还是换行,都能正确读到 a 和 b。但反过来,读取字符串时 cin 遇到空格就会停止,要读取含空格的整行内容,需要使用 getline()(详见后续章节)。使用 cout 搭配插入运算符 << 可以将内容输出到控制台。语法是:cout << 输出内容;,方向正好和 cin 相反——数据从变量传出,流向屏幕:
| 1 | cout << "Hello, World"; // 输出字符串 |
| 2 | cout << 123; // 输出数字 |
| 3 | cout << 3.14; // 输出小数 |
| 4 | |
| 5 | // 用 << 连接多项内容 |
| 6 | int age = 15; |
| 7 | cout << "我今年" << age << "岁"; // 输出:我今年15岁 |
| 8 | |
| 9 | // 两种换行方式 |
| 10 | cout << "第一行" << endl; // endl:换行 + 刷新缓冲区(较慢) |
| 11 | cout << "第二行" << "\n"; // \n:只换行,速度更快 ✓ 推荐 |
和 cin 一样,cout << "我今年" 这个表达式的结果也还是 cout 自己,所以才能一路 << 接龙写下去,把字符串和变量混在一起输出,不需要像有些语言那样手动拼接字符串。
endl 会额外刷新输出缓冲区,速度稍慢;\n 只换行不刷新,速度更快。竞赛编程中大量输出时,推荐用 \n 替代 endl。<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 只管下一个输出对象,用完自动恢复默认宽度;而 setprecision、setfill 一旦设置就会一直生效,直到你再次修改。如果只想让某一个数字加宽,却忘了 setw 只影响一次,就容易写出"后面所有输出宽度都对不齐"的意外效果——这正是因为你以为它像 setprecision 一样是持续生效的。| 指令 | 功能 | 示例 | 输出 |
|---|---|---|---|
| 进制输出 | |||
| 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"读到空格 |
| 指令 | 功能 | 示例 | 输出 |
|---|---|---|---|
| 对齐方式 | |||
| 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 |
把本节内容汇总成几条最容易踩坑的规则:
cin >> str 只能读到第一个空白字符为止,输入"张三 李四"时 str 只会读到"张三"。要读取整行(含空格),必须使用 getline(cin, str)。cin >> n 读取数字后,回车符会残留在输入缓冲区里,紧接着的 getline(cin, str) 会先读到这个残留的空行,导致 str 变成空字符串。混用前记得用 cin.ignore() 清掉残留的换行符。setw(n) 只对紧跟着的下一个输出生效,用完就恢复默认宽度。如果想让后面所有数字都保持固定宽度,必须在每次输出前都重新写一次 setw。fixed 时,setprecision(n) 控制的是"总有效数字位数";一旦加上 fixed,就变成"小数点后的位数"。两种语义混着记很容易算错要保留几位小数。