使用 iostream 进行的输出通常依赖于重载的左移运算符 (<<)(在 iostream 上下文中,称为插入运算符)。要将值输出到标准输出,应将值插入预定义的输出流 cout 中。例如,要将给定值 someValue 发送到标准输出,可以使用以下语句:
cout << someValue; |
对于所有内置类型,都会重载插入运算符,且 someValue 表示的值转换为其适当的输出表示形式。例如,如果 someValue 是 float 值,<< 运算符会将该值转换为带小数点的适当数字序列。此处是将 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 |
以下示例定义了 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,这样就可以在一个语句中合并多个插入。
通常情况下,重载 operator<< 时不必检查错误,因为有 iostream 库传播错误。
出现错误时,所在的 iostream 会进入错误状态。iostream 状态中的各个位根据错误的一般类别进行设置。iostream 中定义的插入器不会尝试将数据插入处于错误状态的任何流,因此这种尝试不会更改 iostream 的状态。
通常,处理错误的推荐方法是定期检查某些中心位置中输出流的状态。如果有错误,就应该以某些方式来处理。本章假定您定义了函数 error,该函数可采用字符串并中止程序。error 不是预定义的函数。有关 error 函数的示例,请参见14.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 io_state {goodbit=0, eofbit=1, failbit=2, badbit=4, hardfail=0x80}; |
有关错误函数的详细信息,请参见 iostream 手册页。
与大多数 I/O 库一样,iostream 通常会累积输出并将其发送到较大且效率通常较高的块中。如果要刷新缓冲区,只要插入特殊值 flush。例如:
cout << "This needs to get out immediately." << flush; |
flush 是一种称为操纵符的对象示例,它是一个值,可以插入 iostream 中以起到一定作用,而不是使输出其值。它实际上是一个函数,采用 ostream& 或 istream& 参数,在对其执行某些操作后返回其参数(请参见14.7 操纵符)。
要获得原始二进制形式的值输出,请使用以下示例所示的成员函数 write。该示例显示了原始二进制形式的 x 输出。
cout.write((char*)&x, sizeof(x)); |
以上示例将 &x 转换为 char*,这违反了类型规程。一般情况下,这样做无关大碍,但如果 x 的类型是具有指针、虚拟成员函数的类或是需要 nontrivial 构造函数操作的类,就无法正确读回以上示例写入的值。