Oracle Solaris Studio 12.2:C++ 用户指南

第 13 章 使用传统 iostream

与 C 类似,C++ 没有内建输入或输出语句。相反,I/O 工具是由库提供的。C++ 编译器提供了 iostream 类的传统实现和 ISO 标准实现。

本章介绍了传统 iostream 库并提供了其使用示例,但并未完整介绍 iostream 库。有关更多详细信息,请参见 iostream 库手册页。要访问传统 iostream 手册页,请键入:man -s 3CC4name

13.1 预定义的 iostream

有四个预定义的 iostream

除了 cerr 之外,所有预定义的 iostream 都是完全缓冲的。请参见13.3.1 使用 iostream 进行输出13.3.2 使用 iostream 进行输入

13.2 iostream 交互的基本结构

通过将 iostream 库包括进来,程序可以使用许多输入流或输出流。每个流都具有某些源或接收器,如下所示:

流可以被限定到输入或输出,或同时具有输入和输出。iostream 库使用两个处理层来实现这些流。

标准输入、输出和错误由从类 istreamostream 派生的特殊类对象处理。

分别从 istreamostreamiostream 派生的 ifstreamofstreamfstream 类用于处理文件的输入和输出。

分别从 istreamostreamiostream 派生的 istrstreamostrstreamstrstream 类用于处理字符数组的输入和输出。

打开输入或输出流时,要创建其中一种类型的对象,并将流的 streambuf 成员与设备或文件关联。通常通过流构造函数执行此关联,因此不用直接使用 streambufiostream 库为标准输入、标准输出和错误输出预定义了流对象,因此不必为这些流创建自己的对象。

可以使用运算符或 iostream 成员函数将数据插入流(输出)或从流(输入)提取数据,以及控制插入或提取的数据的格式。

如果要插入和提取新的数据类型(其中一个类),通常需要重载插入和提取运算符。

13.3 使用传统 iostream

要使用来自传统 iostream 库的例程,必须针对所需的库部分将头文件包括进来。下表对头文件进行了具体描述。

表 13–1 iostream 例程头文件

头文件 

说明  

iostream.h

声明 iostream 库的基本功能。

fstream.h

声明文件专用的 iostreamstreambuf。包括了 iostream.h

strstream.h

声明字符数组专用的 iostreamstreambuf。包括了 iostream.h

iomanip.h

声明操纵符:iostream 中插入或提取的值有不同的作用。包括了 iostream.h

stdiostream.h

(已过时)声明 stdio 文件专用的 iostreamstreambuf。包括了 iostream.h

stream.h

(已过时)包括了 iostream.hfstream.hiomanip.hstdiostream.h。用于兼容 C++ 1.2 版的旧式流。

通常程序中不需要所有这些头文件,而仅包括所需声明的头文件。在兼容模式 (-compat[=4]) 下,传统 iostream 库是 libC 的一部分,它由 CC 驱动程序自动链接。在标准模式(缺省模式)下, libiostream 包含传统 iostream 库。

13.3.1 使用 iostream 进行输出

使用 iostream 进行的输出通常依赖于重载的左移运算符 (<<)(在 iostream 上下文中,称为插入运算符)。要将值输出到标准输出,应将值插入预定义的输出流 cout 中。例如,要将给定值 someValue 发送到标准输出,可以使用以下语句:


cout << someValue;

对于所有内置类型,都会重载插入运算符,且 someValue 表示的值转换为其适当的输出表示形式。例如,如果 someValuefloat<< 运算符会将该值转换为带小数点的适当数字序列。此处是将 float 值插入输出流中,因此 << 称为浮点插入器。通常,如果给定类型 X<< 称为 X 插入器。ios(3CC4) 手册页中讨论了输出格式以及如何控制输出格式。

iostream 库不支持用户定义的类型。如果要定义以自己的方式输出的类型,必须定义一个插入器(即,重载 << 运算符)来正确处理它们。

<< 可以多次应用。要将两个值插入 cout 中,可以使用类似于以下示例中的语句:


cout << someValue << anotherValue;

以上示例的输出在两个值间不显示空格。因此您可能会要按以下方式编写编码:


cout << someValue << " " << anotherValue;

运算符 << 优先作为左移运算符(其内置含义)使用。与其他运算符一样,总是可以使用圆括号来指定操作顺序。使用括号来避免优先级问题是个很好的方法。下列四个语句中,前两个是等价的,但后两个不是。


cout << a+b;              // + has higher precedence than <<
cout << (a+b);
cout << (a&y);            // << has precedence higher than &
cout << a&y;            // probably an error: (cout << a) & y

13.3.1.1 定义自己的插入运算符

以下示例定义了 string 类:


#include <stdlib.h>
#include <iostream.h>


class string {
private:
    char* data;
    size_t size;

public:
    // (functions not relevant here)

    friend ostream& operator<<(ostream&, const string&);
    friend istream& operator>>(istream&, string&);
};

在此示例中,必须将插入运算符和提取运算符定义为友元,因为 string 类的数据部分是 private


ostream& operator<< (ostream& ostr, const string& output)
{    return ostr << output.data;}

以下是为要用于 string 而重载的 operator<< 的定义。


cout << string1 << string2;

运算符 <<ostream&(也就是对 ostream 的引用)作为其第一个参数,并返回相同的 ostream,这样就可以在一个语句中合并多个插入。

13.3.1.2 处理输出错误

通常情况下,重载 operator<< 时不必检查错误,因为有 iostream 库传播错误。

出现错误时,所在的 iostream 会进入错误状态。iostream 状态中的各个位根据错误的一般类别进行设置。iostream 中定义的插入器不会尝试将数据插入处于错误状态的任何流,因此这种尝试不会更改 iostream 的状态。

通常,处理错误的推荐方法是定期检查某些中心位置中输出流的状态。如果有错误,就应该以某些方式来处理。本章假定您定义了函数 error,该函数可采用字符串并中止程序。error 不是预定义的函数。有关 error 函数的示例,请参见13.3.9 处理输入错误。可以使用运算符 ! 检查 iostream 的状态,如果 iostream 处于错误状态,该运算符会返回非零值。例如:


if (!cout) error("output error");

还有另外一种方法来测试错误。ios 类可定义 operator void *(),它在有错误时返回空指针。您可以使用如下语句:


if (cout << x) return; // return if successful

也可以使用函数 good,它是 ios 的成员:


if (cout.good()) return; // return if successful

错误位在 enum 中声明:


enum io_state {goodbit=0, eofbit=1, failbit=2,
badbit=4, hardfail=0x80};

有关错误函数的详细信息,请参见 iostream 手册页。

13.3.1.3 刷新

与大多数 I/O 库一样,iostream 通常会累积输出并将其发送到较大且效率通常较高的块中。如果要刷新缓冲区,只要插入特殊值 flush。例如:


cout << "This needs to get out immediately." << flush;
 

flush 是一种称为操纵符的对象示例,它是一个值,可以插入 iostream 中以起到一定作用,而不是使输出其值。它实际上是一个函数,采用 ostream&istream& 参数,在对其执行某些操作后返回其参数(请参见13.7 操纵符)。

13.3.1.4 二进制输出

要获得原始二进制形式的值输出,请使用以下示例所示的成员函数 write。该示例显示了原始二进制形式的 x 输出。


cout.write((char*)&x, sizeof(x));

以上示例将 &x 转换为 char*,这违反了类型规程。一般情况下,这样做无关大碍,但如果 x 的类型是具有指针、虚拟成员函数的类或是需要 nontrivial 构造函数操作的类,就无法正确读回以上示例写入的值。

13.3.2 使用 iostream 进行输入

使用 iostream 进行的输入类似于输出。需要使用提取运算符 >>,可以像插入操作那样将提取操作串接在一起。例如:


cin >> a >> b;

该语句从标准输入获得两个值。与其他重载运算符一样,所用的提取器取决于 ab 的类型(如果 ab 的类型不同,则使用两个不同的提取器)。ios(3CC4) 手册页中详细讨论了输入格式以及如何控制输入格式。通常,前导空白字符(空格、换行符、标签、换页等)被忽略。

13.3.3 定义自己的提取运算符

要输入新的类型时,如同重载输出的插入运算符,请重载输入的提取运算符。

string 定义了其提取运算符,如以下代码示例所示:


示例 13–1 string 提取运算符


istream& operator>> (istream& istr, string& input)
{
    const int maxline = 256;
    char holder[maxline];
    istr.get(holder, maxline, ”\n’);
    input = holder;
    return istr;
}

get 函数从输入流 istr 读取字符,并将其存储在 holder 中,直到读取了 maxline-1 字符、遇到新行或 EOF(无论先发生哪一项)。然后,holder 中的数据以空终止。最后,holder 中的字符复制到目标字符串。

按照约定,提取器转换其第一个参数中的字符(此示例中是 istream& istr),将其存储在第二个参数(始终是引用),然后返回第一个参数。因为提取器会将输入值存储在第二个参数中,所以第二个参数必须是引用。

13.3.4 使用 char* 提取器

此处提及这个预定义的提取器是因为它可能产生问题。使用方法如下:


char x[50];
cin >> x;

该提取器跳过前导空白,提取字符并将其复制到 x 中,直至遇到另一个空白字符。最后完成具有终止空 (0) 字符的字符串。因为输入会溢出给定的数组,所以要小心操作。

您还必须确保指针指向了分配的存储。例如,下面列出了一个常见的错误:


char * p; // not initialized
cin >> p;

因为没有告知存储输入数据的位置,所以会导致程序的终止。

13.3.5 读取任何单一字符

除了使用 char 提取器外,还可以使用任一形式的 get 成员函数获取一个字符。例如:


char c;
cin.get(c); // leaves c unchanged if input fails

int b;
b = cin.get(); // sets b to EOF if input fails

注 –

与其他提取器不同,char 提取器不会跳过前导空白


以下方法可以只跳过空格,并在制表符、换行符或任何其他字符处停止:


int a;
do {
    a = cin.get();
   }
while(a ==’ ’);

13.3.6 二进制输入

如果需要读取二进制值(如使用成员函数 write 写入的值),可以使用 read 成员函数。以下示例说明了如何使用 read 成员函数输入原始二进制形式的 x,这是先前使用 write 的示例的反向操作。


cin.read((char*)&x, sizeof(x));

13.3.7 查看输入

可以使用 peek 成员函数查看流中的下一个字符,而不必提取该字符。例如:


if (cin.peek()!= c) return 0;

13.3.8 提取空白

缺省情况下,iostream 提取器会跳过前导空白。可以关闭 跳过标志防止这种情况发生。以下示例先关闭了 cin 跳过空白功能,然后将其打开:


cin.unsetf(ios::skipws); // turn off whitespace skipping
...
cin.setf(ios::skipws); // turn it on again

可以使用 iostream 操纵符 wsiostream 中删除前导空白,不论是否启用了跳过功能。以下示例说明了如何从 iostream istr 中删除前导空白:


istr >> ws;

13.3.9 处理输入错误

按照约定,第一个参数为非零错误状态的提取器不能从输入流提取任何数据,且不能清除任何错误位。失败的提取器至少应该设置一个错误位。

对于输出错误,您应该定期检查错误状态,并在发现非零状态时采取某些操作(诸如终止)。! 运算符测试 iostream 的错误状态。例如,如果输入字母字符用于输入,以下代码就会产生输入错误:


#include <stdlib.h>
#include <iostream.h>
void error (const char* message) {
     cerr << message << "\n";
     exit(1);
}
int main() {
     cout << "Enter some characters: ";
     int bad;
     cin >> bad;
     if (!cin) error("aborted due to input error");
     cout << "If you see this, not an error." << "\n";
     return 0;
}

ios 具有可用于错误处理的成员函数。详细信息请参见手册页。

13.3.10 结合使用 iostreamstdio

可以将 stdio 用于 C++ 程序,但在程序内的同一标准流中混合使用 iostreamstdio 时,可能会发生问题。例如,如果同时向 stdoutcout 写入,会发生独立缓冲,并产生不可预料的结果。如果从 stdincin 两者进行输入,问题会更加严重,因为独立缓冲可能会破坏输入。

要消除标准输入、标准输出和标准错误中的这种问题,就请在执行输入或输出前使用以下指令:它将所有预定义的 iostream 与相应的预定义 stdio 文件连接起来。


ios::sync_with_stdio();

因为在预定义流作为连接的一部分成为无缓冲流时,性能会显著下降,所以该连接不是缺省连接。可以在应用于不同文件的同一程序中同时使用 stdioiostream。也就是说,可以使用 stdio 例程向 stdout 写入,并向连接到 iostream 的其他文件写入。可以打开 stdio 文件进行输入,也可以从 cin 读取,只要不同时尝试从 stdin 读取即可。

13.4 创建 iostream

要读取或写入不是预定义的 iostream 的流,需要创建自己的 iostream。通常,这意味着创建 iostream 库中所定义类型的对象。本节讨论了可用的各种类型:

13.4.1 使用类 fstream 处理文件

处理文件类似于处理标准输入和标准输出;类 ifstreamofstreamfstream 分别从类 istreamostreamiostream 派生而来。作为派生的类,它们继承了插入和提取运算符(以及其他成员函数),还有与文件一起使用的成员和构造函数。

可将文件 fstream.h 包括进来以使用任何 fstream。如果只要执行输入,请使用 ifstream;如果只要执行输出,请使用 ofstream;如果要对流执行输入和输出,请使用 fstream。将文件名称用作构造函数参数。

例如,将文件 thisFile 复制到文件 thatFile,如以下示例所示:


ifstream fromFile("thisFile");
if     (!fromFile)
    error("unable to open ’thisFile’ for input");
ofstream toFile ("thatFile");
if     (!toFile)
    error("unable to open ’thatFile’ for output");
char c;
while (toFile && fromFile.get(c)) toFile.put(c);

该代码:

13.4.1.1 打开模式

该模式由枚举类型 open_mode 中的 or-ing 位构造,它是类 ios 的公有类型,其定义如下:


enum open_mode {binary=0, in=1, out=2, ate=4, app=8, trunc=0x10,
     nocreate=0x20, noreplace=0x40};

注 –

UNIX 中不需要 binary 标志,提供该标志是为了与需要它的系统兼容。可移植代码在打开二进制文件时要使用 binary 标志。


您可以打开文件同时用于输入和输出。例如,以下代码打开了文件 someName 用于输入和输出,同时将其连接到 fstream 变量 inoutFile


fstream inoutFile("someName", ios::in|ios::out);

13.4.1.2 在未指定文件的情况下声明 fstream

可以在未指定文件的情况下声明 fstream,并在以后打开该文件。例如,以下代码创建了 ofstream toFile,以便进行写入。


ofstream toFile;
toFile.open(argv[1], ios::out);

13.4.1.3 打开和关闭文件

可以关闭 fstream,然后使用另一文件打开它。例如,要在命令行上处理提供的文件列表:


ifstream infile;
for (char** f = &argv[1]; *f; ++f) {
   infile.open(*f, ios::in);
   ...;
   infile.close();
}

13.4.1.4 使用文件描述符打开文件

如果了解文件描述符(如整数 1 表示标准输出),可以使用如下代码打开它:


ofstream outfile;
outfile.attach(1);

如果通过向 fstream 构造函数之一提供文件名或使用 open 函数来打开文件,则在销毁 fstream(通过 delete 销毁或其超出作用域)时,会自动关闭该文件。将文件 attachfstream 时,不会自动关闭该文件。

13.4.1.5 在文件内重新定位

您可以在文件中改变读取和写入的位置。有多个工具可以达到这个目的。


enum seek_dir {beg=0, cur=1, end=2};

例如,给定 fstream aFile


streampos original = aFile.tellp();     //save current position
aFile.seekp(0, ios::end); //reposition to end of file
aFile << x;               //write a value to file
aFile.seekp(original);    //return to original position

seekg (seekp) 可以采用一个或两个参数。如果有两个参数,第一个参数是相对于 seek_dir 值(也就是第二个参数)指示的位置的位置。例如:


aFile.seekp(-10, ios::end);

从终点移动 10 个字节


aFile.seekp(10, ios::cur);

从当前位置向前移 10 个字节。


注 –

并不能方便地在文本流中进行任意查找,但总是可以返回到以前保存的 streampos 值。


13.5 iostream 赋值

iostream 不允许将一个流赋值给另一个流。

复制流对象的问题是有两个可以独立更改的状态信息版本,例如输出文件中指向当前写入位置的指针。因此,某些问题会发生。

13.6 格式控制

ios(3CC4) 手册页中详细讨论了格式控制。

13.7 操纵符

操纵符是可以在 iostream 中插入或提取以起到特殊作用的值。

参数化操纵符是具有一个或多个参数的操纵符。

因为操纵符是普通的标识符,因此会用完可能的名称,而 iostream 不会为每个可能的函数定义操纵符。本章的其他部分讨论了各种操纵符和成员函数。

有 13 个预定义的操纵符,如表 13–2 中所述。使用该表时,要进行以下假设:

表 13–2 iostream 的预定义操纵符

 

预定义的操纵符  

说明  

ostr << dec、istr >> dec

以 10 为基数进行整数转换。

ostr << endl

插入一个换行符 (’\n’) 并调用 ostream::flush()

ostr << ends

插入一个空 (0) 字符。这在处理 strstream 时很有用。

ostr << flush

调用 ostream::flush()

ostr << hex、istr >> hex

以 16 为基数进行整数转换。

ostr << oct、istr >> oct

以 8 为基数进行整数转换。

istr >> ws

提取空白字符(跳过空白),直至找到非空白字符(留在 istr 中)。

ostr << setbase(n)、istr >> setbase(n)

将转换基数设置为 n(仅限 0、8、10、16)。

ostr << setw(n)、istr >> setw(n)

调用 ios::width(n)。将字段宽度设置为 n。

10 

ostr << resetiosflags(i)、istr >> resetiosflags(i) 

根据 i 中设置的位,清除标志位向量。

11 

ostr << setiosflags(i)、istr >> setiosflags(i)

根据 i 中设置的位,设置标志位向量。

12 

ostr << setfill(c)、istr >> setfill(c)

将填充字符(用来填充字段)设置为 c

13 

ostr << setprecision(n)、istr >> setprecision(n)

将浮点精度设置为 n 位数。

要使用预定义的操纵符,必须在程序中包含文件 iomanip.h

您可以定义自己的操纵符。操纵符共有两个基本类型:

13.7.1 使用无格式操纵符

无格式操纵符是具有如下功能的函数:

由于为 iostream 预定义了采用(指向)此类函数(的指针)的移位运算符,因此可以在输入或输出运算符序列中放入函数。移位运算符会调用函数而不是尝试读取或写入值。例如,下面是将 tab 插入 ostreamtab 操纵符:


ostream& tab(ostream& os) {
             return os <<’\t’;
            }
...
cout << x << tab << y;

详细描述实现以下操作的方法:


const char tab = ’\t’;
...
cout << x << tab << y;

下面示例显示了无法用简单常量来实现的代码。假设要对输入流打开或关闭空白跳过功能。可以分别调用 ios::setfios::unsetf 来打开和关闭 skipws 标志,也可以定义两个操纵符。


#include <iostream.h>
#include <iomanip.h>
istream& skipon(istream &is) {
       is.setf(ios::skipws, ios::skipws);
       return is;
}
istream& skipoff(istream& is) {
       is.unsetf(ios::skipws);
       return is;
}
...
int main ()
{
      int x,y;
      cin >> skipon >> x >> skipoff >> y;
      return 1;
}

13.7.2 参数化操纵符

iomanip.h 中包含的其中一个参数化操纵符是 setfillsetfill 设置用于填写字段宽度的字符。该操作按照下例所示实现:


//file setfill.cc
#include<iostream.h>
#include<iomanip.h>

//the private manipulator
static ios& sfill(ios& i, int f) {
         i.fill(f);
         return i;
}
//the public applicator
smanip_int setfill(int f) {
       return smanip_int(sfill, f);
}

参数化操纵符的实现分为两部分:

头文件 iomanip.h 中定义了多个类。每个类都保存一个操纵符函数的地址和一个参数的值。manip(3CC4) 手册页中介绍了 iomanip 类。上面的示例使用了 smanip_int 类,它是与 ios 一起使用。因为该类与 ios 一起使用,所以也可以与 istreamostream 一起使用。上面的示例还使用了另一个类型为 int 的参数。

applicator 创建并返回类对象。在上面的代码示例中,类对象是 smanip_int,其中包含了操纵符和 applicator 的 int 参数。iomanip.h 头文件定义了用于该类的移位运算符。如果 applicator 函数 setfill 在输入或输出操作序列中,会调用该 applicator 函数,且其返回一个类。移位运算符作用于该类,以使用其参数值(存储在类中)调用操纵符函数。

在以下示例中,操纵符 print_hex

使用类 omanip_long 的原因是该代码示例仅用于输出,而且操作对象是 long 而不是 int


#include <iostream.h>
#include <iomanip.h>
static ostream& xfield(ostream& os, long v) {
        long save = os.setf(ios::hex, ios::basefield);
        os << v;
        os.setf(save, ios::basefield);
        return os;
    }
omanip_long print_hex(long v) {
       return omanip_long(xfield, v);
   }

13.8 用于数组的 strstream: iostream

请参见 strstream(3CC4) 手册页。

13.9 用于 stdio 文件的 stdiobuf: iostream

请参见 stdiobuf(3CC4) 手册页。

13.10 streambuf

iostream 是由两部分(输入或输出)构成的系统的格式化部分。系统的其他部分由处理无格式字符流的输入或输出的 streambuf 组成。

通常,可以通过 iostream 使用 streambuf,因此,不必担心 streambuf 的细节。您可以选择直接使用 streambuf,例如,如果需要提高效率或解决 iostream 内置的处理或格式化错误。

13.10.1 streambuf 工作方式

streambuf 由字符流或字符序列和一个或两个指向相应序列的指针组成。每个指针都指向两个字符间。(实际上,指针无法指向字符间,但可以按这种方式考虑指针。)有两种 streambuf 指针:

streambuf 可以有其中一个指针,也可以两个全有。

13.10.1.1 指针位置

可以使用多种方法来操作指针的位置和序列的内容。操作两个指针时它们是否都会移动取决于使用 streambuf 种类。通常,如果使用队列式 streambuf,get 和 put 指针独立移动;如果使用文件式 streambuf,get 和 put 指针总是一起移动。例如,strstream 是队列式流,fstream 是文件式流。

13.10.2 使用 streambuf

从来不创建实际的 streambuf 对象,而是只创建从 streambuf 类派生的类的对象。例如 filebufstrstreambuffilebuf(3CC4) 手册页和 ssbuf(3) 手册页中分别对它们进行了介绍。高级用户可能想从 streambuf 派生自己的类,以便提供特定设备的接口或提供基本缓冲以外的功能。sbufpub(3CC4) 和 sbufprot(3CC4) 手册页中讨论了如何执行此操作。

除了创建自己的特殊种类的 streambuf 外,您可能还想通过访问与 iostream 关联的 streambuf 来访问公用成员函数(如上面引用的手册页中所述)。此外,每个 iostream 都有采用 streambuf 指针的已定义插入器和提取器。插入或提取 streambuf 时,会复制整个流。

下面是另一种文件复制(前面讨论过)方法,这里为了清晰起见省略了错误检查:


ifstream fromFile("thisFile");
ofstream toFile ("thatFile");
toFile << fromFile.rdbuf();

按照前面所述的方式打开输入和输出文件。每个 iostream 类都有成员函数 rdbuf,它返回指向与其关联的 streambuf 对象的指针。如果是 fstream,则 streambuf 对象是类型 filebuf。与 fromFile 关联的整个文件都复制到(插入)与 toFile 关联的文件。最后一行也可以改写为:


fromFile >> toFile.rdbuf();

然后源文件被提取到目标中。两种方法是完全等同的。

13.11 iostream 手册页

许多 C++ 手册页都介绍了 iostream 库的详细信息。下表概述了每个手册页中的内容。

要访问传统 iostream 库手册页,请键入:


example% man -s 3CC4 name
表 13–3 iostream 手册页概述

手册页 

概述  

filebuf

详细介绍了从 streambuf 派生并专用于文件的类 filebuf 的公用接口。有关从类 streambuf 继承的功能的详细信息,请参见 sbufpub(3CC4) 和 sbufprot(3CC4) 手册页。可通过类 fstream 使用 filebuf 类。

fstream

详细介绍了类 ifstreamofstreamfstream 的专用成员函数,这些类是用于文件的 istreamostreamiostream 专用版本。

ios

详细介绍了作为 iostream 的基类的类 ios 的各个部分。该类也包含了所有流公共的状态数据。

ios.intro

简要介绍了 iostream

istream

详细说明了以下内容: 

  • istream 的成员函数,这些函数支持对从 streambuf 获取的字符进行解释

  • 输入格式化

  • 归为类 ostream 的一部分的定位函数

  • 某些相关函数

  • 相关操纵符

manip

介绍了 iostream 库中定义的输入和输出操纵符。

ostream

详细说明了以下内容: 

  • ostream 的成员函数,这些函数支持对写入 streambuf 的字符进行解释

  • 输出格式化

  • 归为类 ostream 的一部分的定位函数

  • 某些相关函数

  • 相关操纵符

sbufprot

介绍了对从类 streambuf 派生的类进行编码的程序员所需的接口。有关 sbufprot(3CC4) 手册页中未讨论的一些公用函数,另请参见 sbufpub(3CC4) 手册页。

sbufpub

详细介绍了 streambuf 类的公用接口,尤其是 streambuf 的公用成员函数。该手册页包含了直接处理 streambuf 类型的对象所需的信息,或是查找从 streambuf 派生的类从其继承的函数所需的信息。如果要从 streambuf 派生类,另请参见 sbufprot(3CC4) 手册页。

ssbuf

详细介绍了从 streambuf 派生并专用于处理字符数组的类 strstreambuf 的专用公用接口。有关从类 streambuf 继承的功能的详细信息,请参见 sbufpub(3CC4) 手册页。

stdiobuf

简要介绍了从 streambuf 派生并专用于处理 stdio 文件的 stdiobuf 类。有关从 streambuf 类继承的功能的详细信息,请参见 sbufpub(3CC4) 手册页。

strstream

详细介绍了由从 iostream 派生并专用于处理字符数组的一组类实现的 strstream 的专用成员函数。

13.12 iostream 术语

iostream 库说明中常常使用一些与一般编程中的术语类似的术语,但有特殊含义。下表定义了讨论 iostream 库时使用的这些术语。

表 13–4 iostream 术语

iostream 术语

定义  

缓冲区

该词有两个含义,一个特定于 iostream 软件包,另一个较常适用于输入和输出。

iostream 库特定相关时,缓冲区是由类 streambuf 定义的类型的对象。

通常,缓冲区是一个内存块,用于将字符高效传输到输出的输入。对于已缓冲的 I/O,缓冲区已满或被强制刷新之前,字符的实际传输会延迟。 

无缓冲的缓冲区是指在其中没有上文定义的通用意义的缓冲区的 streambuf。本章避免使用缓冲区一词来指 streambuf。但是,手册页和其他 C++ 文档使用缓冲区一词来表示 streambuf

提取

iostream 获取输入的过程。

Fstream

专用于文件的输入或输出流。特指以 courier 字体输出时从类 iostream 派生的类。

插入

将输出发送到 iostream 中的过程。

iostream

通常为输入或输出流。 

iostream

通过 include 文件 iostream.hfstream.hstrstream.hiomanip.hstdiostream.h 实现的库。因为 iostream 是面向对象的库,所以应扩展该库。因此,可以对 iostream 库执行的某些操作并未实现。

通常是指 iostreamfstreamstrstream 或用户定义的流。

Streambuf

包含字符序列的缓冲区,其中字符具有 put 或 get 指针(或兼有)。以 courier 字体输出时,它表示特定类。否则,通常是指 streambuf 类或从 streambuf 派生的类的对象。任何流对象都包含从 streambuf 派生的类型的对象或指向对象的指针。

Strstream

专用于字符数组的 iostream。它是指以 courier 字体输出时的特定类。