提示与输出
cout << "请输入年龄:";
提示要写在读取之前,并说明单位、范围或允许的命令。清楚的输出是程序接口的一部分,不是装饰。
Easy explanation
在服务窗口里,工作人员不会只说一句“输入错误”就离开。他会告诉你需要填写什么、检查内容是否完整,并在错误时让你重新填写。命令行程序也应该这样:先提示,再读取,然后验证,最后才处理。只要少了其中一步,用户就容易不知道程序在等待什么,或者输入一个字母后整个程序再也读不到数字。
cin 适合读取用空格分开的单个数据,getline 适合读取可能包含空格的一整行文字。它们没有谁永远更好,关键是先确定输入的形状。读取年龄可以用 cin,读取“今天完成数学作业”应使用 getline。遇到错误输入时,还要清除输入流的错误状态并丢弃残留字符,否则下一次读取会立刻再次失败。
Core concepts
cout << "请输入年龄:";
提示要写在读取之前,并说明单位、范围或允许的命令。清楚的输出是程序接口的一部分,不是装饰。
cin >> age;
运算符会跳过开头空白并读取一个匹配类型的值。若用户输入字母给整数,输入流会进入失败状态。
getline(cin, name);
getline 一直读取到换行符,因此能保留句子中的空格。cin 之后紧接 getline 时,要先处理遗留换行。
int main(int argc, char* argv[])
argc 表示参数数量,argv 保存每个参数文字。它适合让程序直接接收文件名、模式或初始值。
cout << fixed << setprecision(2) << price;金额通常固定显示两位小数,让输出更像真实工具。
if (!(cin >> age)) { ... }直接检查读取是否成功,不要在失败后继续使用未更新的变量。
cin.ignore(numeric_limits<streamsize>::max(), "\n"[0]);丢弃当前行剩余内容,再进行下一次 getline。
string command; getline(cin, command);整行读取适合 add math homework 这类带空格的命令。
Complete examples
Example 1
普通写法只读取一次,用户输错后程序就结束。更友好的做法是把读取放进循环:类型不对时修复输入流,范围不对时解释规则,只有合法值才离开循环。
这里把年龄限制在 1 到 120。这个范围检查不是 C++ 强制的,而是程序自己的业务规则。类型检查和业务检查要分开思考。
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int age;
while (true)
{
cout << "请输入年龄(1-120):";
if (cin >> age && age >= 1 && age <= 120)
break;
cout << "输入无效,请重新输入。\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "记录成功,年龄:" << age << endl;
}
Example 2
命令行参数让用户在启动程序时就提供信息。例如 greet Mia 3 表示向 Mia 问候三次。argv 中所有内容一开始都是字符串,数字参数需要转换并检查。
argc 至少为 1,因为 argv[0] 通常是程序名。访问 argv[1] 之前必须确认参数数量,否则会读取不存在的位置。
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 3)
{
cout << "用法:greet 名字 次数\n";
return 1;
}
string name = argv[1];
int times = stoi(argv[2]);
if (times < 1 || times > 10)
{
cout << "次数必须在 1 到 10 之间\n";
return 1;
}
for (int i = 0; i < times; ++i)
cout << "你好," << name << "!\n";
}
Algorithm thinking
很多命令行错误并不出在计算公式,而是输入规则没有想清楚。写代码前先列出:用户要输入几个值、每个值是什么类型、允许范围是多少、怎样表示退出、错误后是重试还是结束。规则清楚后,代码结构自然会变成提示、读取、验证、处理和输出。
验证要靠近输入发生的位置。不要先把错误数据传过五个函数,最后才发现结果奇怪。对于菜单程序,可以让每一轮循环只处理一个命令,处理结束后回到菜单;退出命令则改变循环条件。这样新增功能时不会破坏原有流程。
写出类型、范围、是否允许空格以及退出方式。
同时检查输入流状态和业务范围,失败时给出具体原因。
验证通过后再计算,避免错误值进入程序核心。
清理错误状态、丢弃残留内容,并回到清楚的提示位置。
Common mistakes
前一次数字读取留下换行符,getline 立刻把它读走。先 ignore 当前行剩余内容。
只重复 cin 却没有 clear 和 ignore,输入流一直保持失败状态。
没有检查 argc 就访问参数,用户少传参数时可能越界。
只输出“错误”无法帮助用户修正,应说明需要数字、允许范围和示例。
先准备一个最小输入,只保留能够重现问题的几行数据;再在关键步骤输出变量值,确认程序究竟在哪一步偏离预期。编译错误从第一条开始处理,运行错误则比较“实际结果”和“期望结果”。修复后别只重跑原来的例子,还要增加空输入、边界值和错误输入,防止问题换一个形式再次出现。
Homework
建议按顺序完成。前四题帮助巩固语法和基本操作,第五到第七题要求把多个知识点组合起来,第八题是小项目。每道题都要先写输入、处理、输出三行计划,再开始敲代码;程序运行后至少测试正常情况、边界情况和错误情况。
编写 readInt 函数,持续读取指定范围内的整数。分别测试字母、小数、范围外数字和正确数字。
用 getline 读取包含空格的姓名和城市,输出完整自我介绍,不能丢失中间空格。
让用户选择摄氏转华氏或华氏转摄氏,拒绝未知模式,并把结果显示到两位小数。
制作包含查看余额、存入、支出和退出的菜单。每次操作结束后重新显示选项。
允许用户最多输入三次密码,每次失败显示剩余次数,成功或次数用完后结束。
支持 calc 12 + 5 形式的参数,检查参数数量、运算符以及除数是否为零。
把长度、重量和温度换算放进一个程序,每种模式都至少包含两个方向。
完成五个问题的问卷,验证年龄和评分,允许名字含空格,最后输出整齐的汇总报告。
本课验收标准:程序面对错误类型和范围外数据不会崩溃或失去响应;所有提示都说明用户下一步该做什么;至少有一次使用 getline,并能解释 cin 与 getline 的区别。
提交内容应包括源代码、三组测试输入与输出、一个曾经出现的错误及修复方法。最后请用自己的话解释本课最重要的概念;如果只能照着代码念,还需要再独立重写一次核心例子。