输入和输出(I / O)流
输入和输出功能未定义为核心C ++语言的一部分,而是通过C ++标准库提供(因此驻留在std命名空间中)。在前面的课程中,您包含了iostream库头,并使用cin和cout对象来执行简单的I / O. 在本课中,我们将更详细地介绍iostream库。
iostream库
当您包含iostream标头时,您可以访问负责提供I / O功能的整个类层次结构(包括一个实际上名为iostream的类)。非文件I / O类的类层次结构如下所示:
你可能会注意到这个层次结构的第一件事是它使用了多重继承(我们告诉你要尽可能避免这种情况)。但是,iostream库已经过设计和广泛测试,以避免任何典型的多重继承问题,因此您可以自由使用它而无需担心。
流
您可能会注意到的第二件事是“流”一词使用得非常多。最基本的是,C ++中的I / O是用流实现的。抽象地说,流只是一系列可以按顺序访问的字符。随着时间的推移,流可能产生或消耗可能无限量的数据。
通常我们处理两种不同类型的流。 输入流用于保存来自数据生成器的输入,例如键盘,文件或网络。例如,当程序当前不期望任何输入时,用户可以按下键盘上的键。而不是忽略用户按键,数据被放入输入流,在那里它将等待程序准备好它。
相反,输出流用于保存特定数据使用者的输出,例如监视器,文件或打印机。将数据写入输出设备时,设备可能尚未准备好接受该数据,例如,当程序将数据写入其输出流时,打印机可能仍在预热。数据将位于输出流中,直到打印机开始使用它。
某些设备(如文件和网络)能够同时作为输入和输出源。
关于流的好处是程序员只需要学习如何与流交互,以便向许多不同类型的设备读取和写入数据。有关流如何与其连接的实际设备进行交互的详细信息由环境或操作系统决定。
C ++中的输入/输出
尽管ios类通常派生自ios_base,但ios通常是您将直接使用的最基类。ios类定义了一堆输入和输出流共有的东西。我们将在未来的课程中处理这些内容。
istream的类是与输入流处理时所使用的主类。对于输入流,提取运算符(>>)用于从流中删除值。这是有道理的:当用户按下键盘上的键时,键码被放置在输入流中。然后,您的程序从流中提取值,以便可以使用它。
ostream的类是与输出流处理时所使用的主类。对于输出流,插入运算符(<<)用于将值放入流中。这也是有意义的:您将值插入流中,数据使用者(例如监视器)使用它们。
该iostream的类可以同时处理输入和输出,允许双向I / O。
最后,有一堆以“_withassign”结尾的类。这些流类派生自istream,ostream和iostream(分别),并定义了赋值运算符,允许您将一个流分配给另一个。在大多数情况下,您不会直接处理这些类。
C ++中的标准流
标准流是由它的环境提供给计算机程序的预连接的流。C ++附带了四个预定义的标准流对象,这些对象已经设置好供您使用。你见过的前三个:
cin - 与标准输入相关联的istream_withassign类(通常是键盘)
cout - 绑定到标准输出的ostream_withassign类(通常是监视器)
cerr - 与标准错误(通常是监视器)绑定的ostream_withassign类,提供无缓冲输出
clog - 与标准错误(通常是监视器)绑定的ostream_withassign类,提供缓冲输出
通常立即处理无缓冲输出,而缓冲输出通常作为块存储和写出。由于clog不经常使用,因此通常会从标准流列表中省略它。
一个例子
以下是使用标准流的输入和输出示例:
#include <iostream>
#include <cstdlib> // exit()
int main()
{
using namespace std;
// 首先,我们将使用cout上的插入操作符将文本打印到监视器
cout << "Enter your age: " << endl;
//然后我们将使用cin上的提取运算符来获取用户的输入
int nAge;
cin >> nAge;
if (nAge <= 0)
{
//在这种情况下,我们将使用cerr上的插入操作符来打印错误消息
cerr << "Oops, you entered an invalid age!" << endl;
exit(1);
}
// 否则我们将在cout上再次使用插入来打印结果
cout << "You entered " << nAge << " years old" << endl;
return 0;
}
在下一课中,我们将更详细地介绍一些与I / O相关的功能。