输入输出成分
计算机的四大功能是存储、运算、控制和输入输出,我们在第二章细致地讲解了 C++ 程序如何实现其中三个:存储、运算和控制,只剩一个输入输出成分未能讲解。这一节,在有了大量的知识基础之后,我们终于可以讨论一些输入输出相关的问题了。
先让我们从字符串的输入讲起吧。我们上节学到了如何输出一个字符串(字面量或者由字符数组构成):
char a[]{"Hello"};
cout << a << endl;
事实上,你可以直接向字符数组输入字符串(当然,这要求你输入的字符串不能超过 29 位,否则就放不下了),它在输入 Hello!
后会原封不动地输出 Hello!
。比如像这样:
那么再看看这个吧。
啊嘞,为什么只输出了一部分呢?你可以再检查一下 a
的各元素的值,发现确实只存储了 "Hello,"
而没有存储后面的 " world!"
——也就是说后面根本就没输入进去。这是为什么呢?
原因是因为 cin >>
在读入字符串的时候,遇到空格、Tab 和回车就会自动停止读取。停止读取后,程序将输入的字符们串起来,追加 '\0'
,随后存入要输入的字符数组中。那空格及后面的字符呢?它们会留给下一次输入:
这样的程序运行结果如下。
¶Hello, world!↵
string a is: Hello,
string b is: world!
这里,第 6 行和第 7 行的工作原理和我们之前所述相同。但是第 8 行的输入语句并没有等待我们的输入,反而是直接执行了第 9 行的输出。这是为什么呢?这里就需要介绍一个叫做缓冲区的概念。
缓冲区
我们的输入是从键盘这个设备发起的,由我们编写的程序接受。但这个过程并不是直接的,从键盘发出的输入信号需要经过一个叫缓冲区(Data buffer)的东西,然后才能到达我们的程序。具体而言请看下面的动画吧:
总结下来就是:
- 程序从缓冲区读入数据;
- 如果缓冲区是空的,则程序挂起(Suspend)。挂起的含义就是暂停运行,等待用户进行输入操作;
- 键盘上的输入需要在按下回车键(即输入了回车符
'\n'
)才会进入缓冲区; - 程序读取缓冲区的数据遵循一定的规则:如
cin >>
遇到空格停止、忽略空格等等。
那么问题来了,如果我就想读取一个带空格的字符串,该怎么做?cin >>
做不到的,我们还有别的办法。下一节,我们将讲解各种其它常用的字符串输入方法。