输入输出 [从 0 开始的 C++ 之旅 1.2]

📅 2026/7/30 23:51:16 👁️ 阅读次数 📝 编程学习
输入输出 [从 0 开始的 C++ 之旅 1.2]

cout 的流式输出与 endl

在上一节,我们讲到使用 cout 进行输出

cout << "Hello,World!" << endl;

但其实,可以不止输出一次

cout << "Hello,World!" << endl;
cout << "Hello,World!" << endl;

但要是我们需要输出很多不同的内容

cout << "There is no end though there is a start in space -- Infinity." << endl;
cout << "It has own power, it ruins, and it goes though there is a start also in the star -- Finite." << endl;
cout << "Only the person who has wisdom can read the most foolish one from the history." << endl;
cout << "The fish that lives in the sea doesn't know the world in the land. It also ruins and goes if they have wisdom." << endl;
cout << "It is funnier that man exceeds the speed of light than fish start living in the land." << endl;
cout << "It can be said that this is an ultimatum from the god to the people who can fight." << endl;

每输出一句就要多写一句 cout,这太烦人了!其实,cout 是一个字符输出流,它的全称可以是 Character OUTput stream,我们之前所做的其实就是通过流运算符<< 或者接下来会讲到的 >>)将字符“送”到输出流而已,换句话说:我们其实在这样使用 cout

cout << /* 第一个要输出的内容 */ << /* 第二个要输出的内容 */ << /* 省略 */;

我们可以把上面的代码写成这样:

cout << "There is no end though there is a start in space -- Infinity." << endl<< "It has own power, it ruins, and it goes though there is a start also in the star -- Finite." << endl<< "Only the person who has wisdom can read the most foolish one from the history." << endl<< "The fish that lives in the sea doesn't know the world in the land. It also ruins and goes if they have wisdom." << endl<< "It is funnier that man exceeds the speed of light than fish start living in the land." << endl<< "It can be said that this is an ultimatum from the god to the people who can fight." << endl;

你可能会问:前面几行的末尾不需要分号吗?其实这里并不需要,分号的作用是结束语句,而这里我们这几行其实都可以缩成一条语句,所以一定要理解概念

细心的你也许发现了,我们在每一行的末尾都加了 endl,现在解释一下:它是特别用于流换行符,当 cout 接收到 endl 的时候,它会开启新的一行,并刷新缓存区(如果你现在还不清楚什么是缓存区,你可以暂时不理会缓存区这个概念)

使用 cin 输入

在这里先超纲一下,接下来我会使用到下面的语句:

int a;

它的作用就是定义一个叫做 a变量,这个变量可以存放整数。(如果你不知道什么是变量,可以先把它理解成为一个可以用来存东西的盒子。当然这个 a 可以被替换成其他内容,我们会在下一节讲变量的时候深入探究)
我们可以使用 cin 语句输入 a 的值,并使用 cout 输出出来。现在运行代码:

#include <iostream>
using namespace std;
int main() {int a;cin >> a;cout << a;cin >> a;return 0;
}

如果你在使用 Windows,可以直接双击生成的 exe 程序运行,这个时候你会发现它什么都没有输出——它在等你输入。你可以随便输入一个整数,然后按下回车。你会发现你输入的数字被原封不动地输出了!
img
这是为什么?因为我们在一开始调用了一次 cincin 将输入的整数放进了变量 a。然后我们又调用了 cout 输出了一遍!

cin >> a;
cout << a;
cin >> a;

你也许发现我在之后又调用了一次 cin,我这样做的原因让程序变成输入状态,这个时候它会等待你输入,这样你就可以进行观察(不然它就会一闪而过以至于你无法看到输出了什么)
cout 类似,cin 其实代指字符输入流,全称 Character INput stream, 你应该像这样使用 cin

cin >> /*第一个输入的内容*/ >> /*第二个输出的内容*/ >> /* ...省略... */;

流操作符

虽然我们还没正式开始讲操作符,但我还是需要先告知你这两个我们现在接触到的两个操作符:

  • >> 流输入运算符,用于与诸如 cin输入流搭配使用
  • << 流输出运算符,一般与诸如 cout输出流搭配使用

记忆它们很简单,看它们的箭头朝向就知道数据要“流”向哪里。例如 cout << "aaa"; 箭头朝向 cout 所以最后会输出,而 cin >> a; 最后是从 cin 流向外面,所以是输入。

补充:printf 和 scanf

这里只是为了教程的完整性而进行的补充
也许你在其他 C++ 教程里见过另一个版本的 HelloWorld

#include <cstdio> // 或者是 #include <stdio.h>
using namespace std;
int main() {printf("Hello,World!\n");return 0;
}

这其实是为了兼容 C 语言的写法,C 语言使用 printfscanf 进行输入输出,它们并不是流,不能在这里使用 endl。我们会在之后对其进行补充说明,你大可不必担心这个教程会缺斤少两。默认情况下,cout cin 需要和它们进行同步(你没听错,其实 coutprintf 可以混搭,但不建议这么使用),这就导致了 coutcin 的执行效率比它们慢,这就导致了某些人倾向于使用 printfscanf 而不是 cincout,不过你可以不让它们的同步:

ios::sync_with_stdio(false);

你可以上网搜索到更多信息, 不过你要是学过如何使用 printfscanf 也没关系——毕竟用哪个都可以

总结

  • cout字符输出流,使用 << 流操作符进行输出
  • cin字符输入流,使用 >> 流操作符进行输入
  • endl换行仅可用于 coutcin
  • printfscanf 分别是 C 语言风格的输入输出,默认情况下 coutcin 会与它们进行同步,使用 ios::sync_with_stdio(false) 关闭两者的同步
  • 下面的语句可以定义一个整型变量(存放整数的变量),它的变量名叫做 a
int a;

变量的内容将在下一节涉及

练习

Debug

下面这段代码哪里出错了?

#include <iostream>
using namespace std;
int main() {cout << "Hello,World";<< endl;return 0;
}
查看答案

"Hello,World!" 后面多了一个分号,这个分号导致语句提前结束了。把它去掉就能正常工作了

#include <iostream>
using namespace std;
int main() {cout << "Hello,World"<< endl;return 0;
}

输入输出练习

编写程序,要求给出提示要求用户输入一个整数,然后把它原封不动地输出三次,就像这样:

输入一个整数:114514
你输入了114514
你输入了114514
你输入了114514
重要的事情说三遍
查看答案
#include <iostream>
using namespace std;
int main() {int num;cout << "输入一个整数:";cin >> num;cout << "你输入了" << num << endl<< "你输入了" << num << endl<< "你输入了" << num << endl<< "重要的事情说三遍" << endl;return 0;
}

Debug 2

这段代码这样写有没有问题?这会导致什么?(你可以复制这段代码并运行)

#include <iostream>
using namespace std;
int main() {ios::sync_with_stdio(false);cout << "Hello,";printf("World!");cout << endl;printf("Hello,");cout << "World!" << endl;return 0;
}
查看答案

先说问题:它在使用 ios::sync_with_stdio(false)混用了 coutprintf 这会导致一个未定义行为(UB, Undefined Behavior)
什么是未定义行为?举个例子:你买了一个挖掘机,它应该被用来挖地,而你却试图用它来梳头发,站在挖掘机生产厂商的角度看,我应该在说明书上注明你应该怎样拿它梳头发吗?那肯定是不——因为拿挖掘机梳头发的人简直就是神经病或者说有点SM癖好
回到这里,你使用了 ios::sync_with_stdio(false) 关闭了 cout cinprintf scanf 的同步,然后你用混用它们你是不是故意找茬,C++ 标准的制定者没必要定义这会导致什么——毕竟你关闭了它们的同步,再混用,后果自负。所以具体会发生什么谁也不知道(实际上这里的混用往往会导致输出乱序
实际上 C++ 标准定义了什么是未定义行为,为什么要这样?因为定义某些行为为未定义行为,可以给予一些编译器优化的自由。
未定义行为我们会在后面专门进行讨论