1. 流和缓存
C++程序把输入和输出当作字节流,对于面向文本的程序,每个字节对应一个字符。流stream充当程序与流的起点或终点之间的媒介,连接程序端与文件端。文件端可以是文件,也可以是设备,比如键盘和屏幕。
缓存buffer是一块内存,充当程序与设备之间信息交换的临时存储1。一般地,设备,比如硬盘,通常以512字节(或更多)为单位传输信息,而程序每次处理一个字节信息。而且,从内存中读单个字节,比从硬盘中更快。缓存帮助匹配两个不同速率的数据交换:从硬盘中读取一块数据,保存在缓存中,再从缓存中每次读取一个字节,读完后(清空缓存flush the buffer)再从硬盘取一块数据放到缓存;反方向,向缓存每次写入一个字节,写满缓存后再一次性写入硬盘(清空缓存),然后再向缓存写入数据。缓存法比单字节读写法(byte-by-byte)更快和更简单。
在将输入数据传给程序前,缓存法键盘输入允许用户备份和修改输入信息。通常,C++程序在用户按下回车键Enter
时清空输入缓存,当用户输出换行符(newline character)时清空输出缓存,都不必等到缓存填满。
2. 标准输入和输出流
C++提供了多个类来实现和管理流和缓存:
类 class | 描述 |
---|---|
streambuf | 为缓存提供内存,并一同提供用于填充缓存、访问缓存内容、清空缓存和管理缓存内存的类方法。 |
ios_base | 表示流的一般属性,比如是否打开用于读取和是二进制流还是文本流。 |
ios | 基于ios_base class,包括一个指向streambuf对象的指针成员。 |
ostream | 衍生自ios,提供输出方法。 |
istream | 衍生自ios,提供输入方法。 |
iostream | 基于istream和ostream,继承两者的输入和输出方法。 |
在C++程序中包括头文件<iostream>
(在该头文件中声明的对象有外部链接性external linkage和静态生存期static duration2)将自动创建8个流对象(窄字符34个,宽字符44个):
cin
对应标准输入流(standard input stream):默认与标准输入设备(一般是键盘)相关联。cout
对应标准输出流(standard output stream):默认与标准输出设备(一般是显示器)相关联。cerr
对应标准错误流(standard error stream):默认与标准输出设备(一般是显示器)相关联,而且该流不缓存,直接把错误信息发送到屏幕,不等缓存填满或换行符(newline character)。clog
对应标准错误流(standard error stream):默认与标准输出设备(一般是显示器)相关联,而且缓存。
C stream | C++ stream | 默认关联设备 | 缓存 |
---|---|---|---|
stdin | cin | 键盘 | 是 |
stdout | cout | 显示器 | 是 |
stderr | cerr | 显示器 | 否 |
— | clog | 显示器 | 是 |
默认cin
与stdin
同步,cout
与stdout
同步。cin
绑定于cout
,意味着在对cin
执行I/O操作之前先清空cout
缓存。而cout
不与任何其他输出流绑定。
3. 字符输入和输出
#include <istream>
// single character
int get(void); // return character read or EOF if failure
istream & get(char & c); // return invoking object reference
#include <ostream>
// single character
ostream & put(char c); // return invoking object reference
get()
函数有三种模式:单字节模式(见上面代码片段)、C风格字符串模式和流缓存模式。而且字符输入所使用单字节模式也有两种签名:第一种签名与C语言字符输入的gtechar
函数等价,无参数,返回读取的字符,如果出错返回EOF
;第二种签名与put()
函数的一致,将读取的字符赋值给引用参数所指示的char
型变量,返回调用对象引用,所以支持输入级联(concatenation)。
#include <iostream>
using namespace std;
int main(int argc, char const *argv[]) {
char a;
char b;
char c;
cout << "Enter no less than 3 characters: \n";
a = cin.get(); // int get(void)
cin.get(b).get(c); // istream & get(char & c)
cout.put(a).put(b).put(c).put('\n'); // ostream & put(char c)
return 0;
}
输出
Enter no less than 3 characters:
RMB