Skip to content

第 5 章 让程序跟你聊天


🏗️ 前情回顾:第 3 章学了变量,第 4 章扩充了类型工具箱。现在把这些组合起来,让程序能跟人对话。


🎯 本章目标

学完这一章,你能:

  • cin 接收用户输入的各种类型数据
  • cout 格式化输出——控制换行、空格、小数位数
  • 理解输入缓冲区的概念(为什么输入完要按回车)
  • 写一个能跟用户互动的小程序

📖 故事引入

前几章你的程序都是"自言自语"——你事先写死了所有内容,程序跑一遍就结束。

但现在想想真正的应用程序:你在搜索框里打字,搜索结果就变了;你在游戏里按方向键,角色就移动。这些程序跟你的程序最大的区别是什么?

它们能接收你的输入,然后根据输入做出不同的反应。

这就是本章要学的:让你的程序不再自言自语,而是跟人对话


🧱 知识讲解

5.1 cin:让程序听你说话

cin(c + in = character input)是 C++ 的标准输入。它等你在键盘上敲东西,然后把你敲的内容读进变量。

cpp
// ❌ 错误:箭头方向反了!
// cin << age;   // 编译错误

// ✅ 正确:数据从键盘流向变量,箭头指向变量
int age;
cout << "请输入你的年龄:";
cin >> age;
cout << "你今年 " << age << " 岁" << endl;

运行效果:

请输入你的年龄:12
你今年 12 岁

注意 >> 的方向:cout << 是数据往外流(程序 → 屏幕),cin >> 是数据往内流(键盘 → 程序)。

5.2 可以读入任何类型

第 3 章学的六种类型,cin 都能读:

cpp
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 可以用空格或换行分隔多个输入:

cpp
int a, b;
cin >> a >> b;        // 用户输入 "10 20",a=10, b=20
cout << a + b << endl;  // 输出 30

用户既可以在一行里用空格分开输入(10 20),也可以分两行输入(先敲 10 回车,再敲 20 回车)。cin 会自动跳过空白字符。

5.4 综合示例:友好的对话程序

cpp
#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 的输出控制

换行

cpp
cout << "第一行" << endl;   // endl = 换行
cout << "第二行\n";         // \n 也是换行(在字符串内部)
cout << "第三行";           // 没有换行,下个输出会接在后面

endl\n 都能换行。现阶段用 endl 就行,它更直观——end line,结束这一行。\n 以后学到大量输出的时候你会自然喜欢上它。

输出多个东西

cpp
cout << "身高:" << 175 << "cm" << endl;
// 用 << 把文字、数字、变量串起来

控制浮点数小数位数

cpp
// ❌ 错误:只有 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.1416
  • fixed = "用定点格式显示"(就是正常小数点)
  • 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 忘了 fixedcout << 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 个错误:

cpp
int x;
cin << x;
cout << fixed << setprecision(2) << x

(提示:少了一个头文件,箭头方向错了,少了一个分号。)

提高题

5. 编程题 — 计算器

写一个程序,让用户输入两个整数,分别输出:和、差、积、商(整数除法)和余数。

示例运行:

请输入两个整数:17 5
和 = 22
差 = 12
积 = 85
商 = 3
余数 = 2

6. 编程题 — 自我介绍

写一个程序,依次询问用户的姓名(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题从简单格式化→多类型→大数输入逐级递进。。★核心(课堂必做) ◆拓展(课后练习)

级别题号链接覆盖知识点
★ 核心J0007https://hydro.ac/d/srqc/p/J0007cin>>、cout、输入→处理→输出全链路
◆ 拓展luogu-B2027https://hydro.ac/p/luogu-B2027cin、double、printf格式控制
◆ 拓展luogu-B2021https://hydro.ac/p/luogu-B2021printf、保留3位小数
◆ 拓展luogu-B2022https://hydro.ac/p/luogu-B2022printf、保留12位、精度概念
◆ 拓展luogu-B2023https://hydro.ac/p/luogu-B2023多类型混合输出、空格分隔
◆ 拓展luogu-B2024https://hydro.ac/p/luogu-B2024浮点输出、科学计数法认识
◆ 拓展luogu-B2033https://hydro.ac/p/luogu-B2033cin、long long、大数输入意识

💡 练习建议:先完成 1 道★核心题,确保掌握本章基本方法;再完成 6 道◆拓展题,覆盖不同变式和细节。


配套练习

共7题。核心1题讲cin/cout链路,拓展6题从简单格式化→多类型→大数输入逐级递进。★核心(课堂必做) · ◆拓展(课后练习)

级别题号链接覆盖知识点
★ 核心J0007https://hydro.ac/d/srqc/p/J0007cin>>、cout、输入→处理→输出全链路
◆ 拓展luogu-B2027https://hydro.ac/p/luogu-B2027cin、double、printf格式控制
◆ 拓展luogu-B2021https://hydro.ac/p/luogu-B2021printf、保留3位小数
◆ 拓展luogu-B2022https://hydro.ac/p/luogu-B2022printf、保留12位、精度概念
◆ 拓展luogu-B2023https://hydro.ac/p/luogu-B2023多类型混合输出、空格分隔
◆ 拓展luogu-B2024https://hydro.ac/p/luogu-B2024浮点输出、科学计数法认识
◆ 拓展luogu-B2033https://hydro.ac/p/luogu-B2033cin、long long、大数输入意识

练习建议:先在课堂完成 1 道★核心题,掌握本章基本方法;课后完成 6 道◆拓展题,覆盖不同变式和细节。

自查清单

  • [ ] 我会用 cin >> 读入 int、double、char、string、bool
  • [ ] 我会用 cout << 输出,能控制换行和小数位数
  • [ ] 我知道 #include <iomanip> 是干什么的
  • [ ] 我知道输入缓冲区是什么
  • [ ] 我能写出一个跟用户互动的对话程序

🚀 下章预告:会输入输出了。下一章让程序做它最擅长的事——计算。