输入和输出功能并非 C++ 核心语言的一部分,而是通过 C++ 标准库(因此位于 std 命名空间中)提供。在之前的课程中,您包含了 iostream 库头文件并使用了 cin 和 cout 对象进行简单的 I/O。在本课程中,我们将更详细地了解 iostream 库。
iostream 库
当您包含 iostream 头文件时,您将获得一个负责提供 I/O 功能的完整类层次结构(其中一个类实际上名为 iostream)。您可以在此处找到非文件 I/O 类的类层次结构图。
您可能首先注意到这个层次结构使用了多重继承(我们告诉您尽可能避免的事情)。然而,iostream 库已经经过设计和广泛测试,以避免任何典型的多重继承问题,因此您可以自由使用它而无需担心。
流
您可能注意到的第二件事是“流”这个词被大量使用。最基本地,C++ 中的 I/O 是通过流实现的。抽象地讲,一个**流**只是一系列可以按顺序访问的字节。随着时间的推移,流可能会产生或消耗无限量的数据。
通常我们处理两种不同类型的流。**输入流**用于保存来自数据生产者(如键盘、文件或网络)的输入。例如,用户可能会在程序当前不期望任何输入时按下键盘上的键。数据不会被忽略,而是被放入输入流中,在那里它会等待程序准备好处理它。
相反,**输出流**用于保存特定数据消费者(如显示器、文件或打印机)的输出。当向输出设备写入数据时,设备可能尚未准备好接受该数据——例如,当程序向其输出流写入数据时,打印机可能仍在预热。数据将停留在输出流中,直到打印机开始消耗它。
一些设备,如文件和网络,既可以是输入源,也可以是输出源。
流的好处在于,程序员只需学习如何与流交互,即可将数据读取和写入多种不同类型的设备。流如何与它们所连接的实际设备接口的详细信息则留给环境或操作系统处理。
C++ 中的输入/输出
ios
是 std::basic_ios<char>
的 typedef,它定义了输入流和输出流共有的许多内容。我们将在未来的课程中处理这些内容。
**istream** 类是处理输入流时使用的主要类。对于输入流,**提取运算符 (>>) ** 用于从流中移除值。这很有意义:当用户按下键盘上的键时,键码被放入输入流中。然后您的程序从流中提取该值以便使用。
**ostream** 类是处理输出流时使用的主要类。对于输出流,**插入运算符 (<<) ** 用于将值放入流中。这同样有意义:您将值插入流中,数据消费者(例如显示器)使用它们。
**iostream** 类可以同时处理输入和输出,实现双向 I/O。
C++ 中的标准流
**标准流**是由其环境提供给计算机程序的预连接流。C++ 附带了四个预定义标准流对象,这些对象已为您设置好。前三个您之前见过:
- cin -- 一个绑定到标准输入(通常是键盘)的 istream 对象
- cout -- 一个绑定到标准输出(通常是显示器)的 ostream 对象
- cerr -- 一个绑定到标准错误(通常是显示器)的 ostream 对象,提供无缓冲输出
- clog -- 一个绑定到标准错误(通常是显示器)的 ostream 对象,提供缓冲输出
无缓冲输出通常会立即处理,而缓冲输出通常会被存储并作为块写入。由于 clog 不常用,因此它通常被省略在标准流列表中。
在下一课中,我们将更详细地了解一些 I/O 相关功能。