第 5 章 让程序跟你聊天
🏗️ 前情回顾:第 3 章学了变量,第 4 章扩充了类型工具箱。现在把这些组合起来,让程序能跟人对话。
🎯 本章目标
学完这一章,你能:
- 用
cin接收用户输入的各种类型数据 - 用
cout格式化输出——控制换行、空格、小数位数 - 理解输入缓冲区的概念(为什么输入完要按回车)
- 写一个能跟用户互动的小程序
📖 故事引入
前几章你的程序都是"自言自语"——你事先写死了所有内容,程序跑一遍就结束。
但现在想想真正的应用程序:你在搜索框里打字,搜索结果就变了;你在游戏里按方向键,角色就移动。这些程序跟你的程序最大的区别是什么?
它们能接收你的输入,然后根据输入做出不同的反应。
这就是本章要学的:让你的程序不再自言自语,而是跟人对话。
🧱 知识讲解
5.1 cin:让程序听你说话
cin(c + in = character input)是 C++ 的标准输入。它等你在键盘上敲东西,然后把你敲的内容读进变量。
// ❌ 错误:箭头方向反了!
// cin << age; // 编译错误
// ✅ 正确:数据从键盘流向变量,箭头指向变量
int age;
cout << "请输入你的年龄:";
cin >> age;
cout << "你今年 " << age << " 岁" << endl;运行效果:
请输入你的年龄:12
你今年 12 岁注意 >> 的方向:cout << 是数据往外流(程序 → 屏幕),cin >> 是数据往内流(键盘 → 程序)。
5.2 可以读入任何类型
第 3 章学的六种类型,cin 都能读:
int age; cin >> age; // 读整数
long long big; cin >> big; // 读大整数
double score; cin >> score; // 读小数
char grade; cin >> grade; // 读单个字符
string name; cin >> name; // 读一个单词
bool flag; cin >> flag; // 读 1(true)或 0(false)⚠️ 用
cin >>读 string 时,遇到空格就停止。如果用户叫"张 三",cin >> name只能读到"张"。解决方法是getline(后面章节会讲)。
5.3 一行输入多个值
cin 可以用空格或换行分隔多个输入:
int a, b;
cin >> a >> b; // 用户输入 "10 20",a=10, b=20
cout << a + b << endl; // 输出 30用户既可以在一行里用空格分开输入(10 20),也可以分两行输入(先敲 10 回车,再敲 20 回车)。cin 会自动跳过空白字符。
5.4 综合示例:友好的对话程序
#include <iostream>
#include <string> // 用 string 需要这个
using namespace std;
int main() {
string name;
int age;
double score;
cout << "你叫什么名字?";
cin >> name;
cout << "你今年几岁?";
cin >> age;
cout << "上次考试考了多少分?";
cin >> score;
cout << "———— 档案卡 ————" << endl;
cout << "姓名:" << name << endl;
cout << "年龄:" << age << " 岁" << endl;
cout << "分数:" << score << " 分" << endl;
return 0;
}运行效果:
你叫什么名字?小明
你今年几岁?13
上次考试考了多少分?96.5
———— 档案卡 ————
姓名:小明
年龄:13 岁
分数:96.5 分5.5 cout 的输出控制
换行:
cout << "第一行" << endl; // endl = 换行
cout << "第二行\n"; // \n 也是换行(在字符串内部)
cout << "第三行"; // 没有换行,下个输出会接在后面endl 和 \n 都能换行。现阶段用 endl 就行,它更直观——end line,结束这一行。\n 以后学到大量输出的时候你会自然喜欢上它。
输出多个东西:
cout << "身高:" << 175 << "cm" << endl;
// 用 << 把文字、数字、变量串起来控制浮点数小数位数:
// ❌ 错误:只有 setprecision,没有 fixed
cout << setprecision(2) << 3.14159 << endl; // 可能输出 3.1(只控制有效数字)
// ✅ 正确:fixed + setprecision 一起用才保留小数位
#include <iomanip> // 格式化输出的工具
// ...
double pi = 3.14159265;
cout << fixed << setprecision(2) << pi << endl; // 输出 3.14
cout << fixed << setprecision(4) << pi << endl; // 输出 3.1416fixed= "用定点格式显示"(就是正常小数点)setprecision(2)= "保留 2 位小数"
💡 你会发现有些工具需要额外的
#include才能用。cin/cout需要<iostream>,string需要<string>,setprecision需要<iomanip>。这是 C++ 的习惯——用啥拿啥,不浪费。
5.6 输入缓冲区的概念
当你敲键盘的时候,字符不是直接送进程序的。它们先暂存在一个叫输入缓冲区的地方。等你按下回车键,缓冲区里的内容才一次性交给程序处理。
这就是为什么你可以慢慢打字,程序不会反应——它还在等你按回车。
✋ 动手试试
试试 1:写程序问用户"你最喜欢什么数字?",读入后显示"哇![数字] 也是我最喜欢的数字!"
试试 2:让用户输入三个科目的分数,计算并输出总分和平均分(保留 2 位小数)。用 <iomanip>。
试试 3:写一个程序,依次读入一个 char、一个 string、一个 bool,然后原样输出。看看 bool 输出什么。
⚠️ 你踩过这些坑吗
- [ ] 坑 1:cin 方向写反 —
cin << age;箭头方向错了。数据流进变量是cin >> age;。 - [ ] 坑 2:读 string 没加
#include <string>— 用了string name; cin >> name;但文件头没有#include <string>。 - [ ] 坑 3:中英文符号再次出现 —
cout << "你好";中文分号!永远用英文标点。 - [ ] 坑 4:用 setprecision 忘了 fixed —
cout << setprecision(2) << 3.14159;可能输出 3.1。加fixed才是"保留 N 位小数"。
📝 练习
基础题
1. 填空题
(1)从键盘读入数据的 C++ 关键字是 ____。
(2)输出时保留 2 位小数,需要 cout << \_\_\_\_ << \_\_\_\_(2) << 数字;
(3)输入缓冲区的数据在按下 ____ 键后一次性交给程序。
2. 选择题
(1)以下哪个是正确读取用户输入的写法? A. cin << x; B. cin >> x; C. cout >> x; D. input(x);
(2)用 cin >> name; 读取字符串,用户输入"张三 李四",name 里存的是什么? A. 张三李四 B. 张三 C. 张三 李四 D. 编译错误
3. 判断题
(1)cout << fixed << setprecision(2) << 3.14159; 输出 3.14。( ) (2)cin >> a >> b; 可以在一行里读取两个数。( ) (3)endl 和 \n 都能换行。( )
4. 代码改错
找出下面代码的 3 个错误:
int x;
cin << x;
cout << fixed << setprecision(2) << x(提示:少了一个头文件,箭头方向错了,少了一个分号。)
提高题
5. 编程题 — 计算器
写一个程序,让用户输入两个整数,分别输出:和、差、积、商(整数除法)和余数。
示例运行:
请输入两个整数:17 5
和 = 22
差 = 12
积 = 85
商 = 3
余数 = 26. 编程题 — 自我介绍
写一个程序,依次询问用户的姓名(string)、年龄(int)、身高(double,单位米)、最喜欢的科目(string)。然后输出一段完整的自我介绍,身高保留 2 位小数。
7. 编程题 — 圆的计算
让用户输入圆的半径 r(double),计算并输出圆的周长($2\pi r$)和面积($\pi r^2$)。π 取 3.14159,周长和面积各保留 2 位小数。
挑战题
8. 编程题 — 时间转换
让用户输入一个秒数(例如 3665),程序把它转换成"X 小时 Y 分 Z 秒"的格式。
示例运行:
请输入秒数:3665
3665 秒 = 1 小时 1 分 5 秒(提示:1 小时 = 3600 秒,1 分钟 = 60 秒,善用 / 和 % 运算。)
9. 编程题 — 找零计算器
模拟超市收银:用户输入"商品总价"和"付款金额"(都是 double),程序输出找零金额(保留 2 位小数)。如果付款不够,提示"金额不足"。
🧠 本章小结
输入:cin >> 变量; ← 数据往里流(键盘→程序)
输出:cout << 内容; ← 数据往外流(程序→屏幕)
换行:endl 或 \n
小数:fixed + setprecision(N) ← 需 #include <iomanip>
输入缓冲区:你打字 → 暂存 → 按回车 → 一次性交给程序📝 配套练习
共7题。核心1题讲cin/cout链路,拓展6题从简单格式化→多类型→大数输入逐级递进。。★核心(课堂必做) ◆拓展(课后练习)
| 级别 | 题号 | 链接 | 覆盖知识点 |
|---|---|---|---|
| ★ 核心 | J0007 | https://hydro.ac/d/srqc/p/J0007 | cin>>、cout、输入→处理→输出全链路 |
| ◆ 拓展 | luogu-B2027 | https://hydro.ac/p/luogu-B2027 | cin、double、printf格式控制 |
| ◆ 拓展 | luogu-B2021 | https://hydro.ac/p/luogu-B2021 | printf、保留3位小数 |
| ◆ 拓展 | luogu-B2022 | https://hydro.ac/p/luogu-B2022 | printf、保留12位、精度概念 |
| ◆ 拓展 | luogu-B2023 | https://hydro.ac/p/luogu-B2023 | 多类型混合输出、空格分隔 |
| ◆ 拓展 | luogu-B2024 | https://hydro.ac/p/luogu-B2024 | 浮点输出、科学计数法认识 |
| ◆ 拓展 | luogu-B2033 | https://hydro.ac/p/luogu-B2033 | cin、long long、大数输入意识 |
💡 练习建议:先完成 1 道★核心题,确保掌握本章基本方法;再完成 6 道◆拓展题,覆盖不同变式和细节。
配套练习
共7题。核心1题讲cin/cout链路,拓展6题从简单格式化→多类型→大数输入逐级递进。★核心(课堂必做) · ◆拓展(课后练习)
| 级别 | 题号 | 链接 | 覆盖知识点 |
|---|---|---|---|
| ★ 核心 | J0007 | https://hydro.ac/d/srqc/p/J0007 | cin>>、cout、输入→处理→输出全链路 |
| ◆ 拓展 | luogu-B2027 | https://hydro.ac/p/luogu-B2027 | cin、double、printf格式控制 |
| ◆ 拓展 | luogu-B2021 | https://hydro.ac/p/luogu-B2021 | printf、保留3位小数 |
| ◆ 拓展 | luogu-B2022 | https://hydro.ac/p/luogu-B2022 | printf、保留12位、精度概念 |
| ◆ 拓展 | luogu-B2023 | https://hydro.ac/p/luogu-B2023 | 多类型混合输出、空格分隔 |
| ◆ 拓展 | luogu-B2024 | https://hydro.ac/p/luogu-B2024 | 浮点输出、科学计数法认识 |
| ◆ 拓展 | luogu-B2033 | https://hydro.ac/p/luogu-B2033 | cin、long long、大数输入意识 |
练习建议:先在课堂完成 1 道★核心题,掌握本章基本方法;课后完成 6 道◆拓展题,覆盖不同变式和细节。
自查清单:
- [ ] 我会用
cin >>读入 int、double、char、string、bool - [ ] 我会用
cout <<输出,能控制换行和小数位数 - [ ] 我知道
#include <iomanip>是干什么的 - [ ] 我知道输入缓冲区是什么
- [ ] 我能写出一个跟用户互动的对话程序
🚀 下章预告:会输入输出了。下一章让程序做它最擅长的事——计算。