#include <iostream.h> typedef long streampos; typedef long streamoff; class unsafe_ios { public: // exported types
// stream operation mode enum open_mode { in = 0x01, // open for reading out = 0x02, // open for writing ate = 0x04, // seek to eof upon original open app = 0x08, // append mode: all additions at eof trunc = 0x10, // truncate file if already exists nocreate = 0x20, // open fails if file doesn't exist noreplace= 0x40 // open fails if file already exists };
// stream seek direction enum seek_dir { beg=0, cur=1, end=2 };
// formatting flags enum { skipws = 0x0001, // skip whitespace on input left = 0x0002, // left-adjust output right = 0x0004, // right-adjust output internal = 0x0008, // padding after sign or base indicator dec = 0x0010, // decimal conversion oct = 0x0020, // octal conversion hex = 0x0040, // hexidecimal conversion showbase = 0x0080, // use base indicator on output showpoint = 0x0100, // force decimal point (floating output) uppercase = 0x0200, // upper-case hex output showpos = 0x0400, // add '+' to positive integers scientific= 0x0800, // use 1.2345E2 floating notation fixed = 0x1000, // use 123.45 floating notation unitbuf = 0x2000, // flush all streams after insertion stdio = 0x4000 // flush stdout, stderr after insertion };
// see ios(3CC4) for remainder ... }; class unsafe_ostream : virtual public unsafe_ios { public: // exported functions // unformatted output functions unsafe_ostream& put(char c); unsafe_ostream& write(const char* ptr, int len); // wide character unsafe_ostream& put(wchar_t wc); unsafe_ostream& write(const wchar_t * wptr, int len); // other functions int opfx(); void osfx(); unsafe_ostream& flush(); unsafe_ostream& seekp(streampos pos); unsafe_ostream& seekp(streamoff offset, unsafe_ios::seek_dir from); streampos tellp(); public: // exported operator functions unsafe_ostream& operator<< (char); unsafe_ostream& operator<< (unsigned char); unsafe_ostream& operator<< (short); unsafe_ostream& operator<< (unsigned short); unsafe_ostream& operator<< (int); unsafe_ostream& operator<< (unsigned int); unsafe_ostream& operator<< (long); unsafe_ostream& operator<< (unsigned long); unsafe_ostream& operator<< (float); unsafe_ostream& operator<< (double); unsafe_ostream& operator<< (const char* buf); unsafe_ostream& operator<< (void* ptr); unsafe_ostream& operator<< (streambuf* sbufp); unsafe_ostream& operator<< (unsafe_ostream& (*manip)(unsafe_ostream&)); unsafe_ostream& operator<< (unsafe_ios& (*manip)(unsafe_ios&)); public: // wide character unsafe_ostream& operator<< (wchar_t); unsafe_ostream& operator<< (const wchar_t*); public: // exported constructors unsafe_ostream(streambuf* sbufp); }; class ostream : virtual public ios, public unsafe_ostream { public: // unformatted output functions ostream& put(char); ostream& write(const char* ptr, int n); ostream& write(const unsigned char* ptr, int n); // wide character ostream& put(wchar_t); ostream& write(const wchar_t *, int);
// other functions int opfx(); int osfx(); ostream& flush(); ostream& seekp(streampos); ostream& seekp(streamoff, seek_dir); streampos tellp(); public: // exported operator functions ostream& operator<<(char); ostream& operator<<(unsigned char); ostream& operator<<(short); ostream& operator<<(unsigned short); ostream& operator<<(int); ostream& operator<<(unsigned int); ostream& operator<<(long); ostream& operator<<(unsigned long); ostream& operator<<(float); ostream& operator<<(double); ostream& operator<<(const char*); ostream& operator<<(void*); ostream& operator<<(streambuf*); ostream& operator<<(ostream& (*)(ostream&)); ostream& operator<<(ios& (*)(ios&)); public: // wide character ostream& operator<< (wchar_t); ostream& operator<< (const wchar_t*); public: // exported constructor ostream(streambuf* sbufp);
}; class ostream_withassign : public ostream { public: ostream_withassign(); ostream_withassign& operator= (ostream& ostr); ostream_withassign& operator= (streambuf* sbufp); }; extern ostream_withassign cout; extern ostream_withassign cerr; extern ostream_withassign clog; ios& dec(ios&); ios& hex(ios&); ios& oct(ios&); ostream& endl(ostream&); ostream& ends(ostream&); ostream& flush(ostream&); unsafe_ios& dec(unsafe_ios&) ; unsafe_ios& hex(unsafe_ios&) ; unsafe_ios& oct(unsafe_ios&) ; unsafe_ostream& endl(unsafe_ostream& i) ; unsafe_ostream& ends(unsafe_ostream& i) ; unsafe_ostream& flush(unsafe_ostream&) ;
类 ostream 支持从关联的 streambuf 执行有格式的和无格式的数据插入(输出)。
类 unsafe_ostream 实现了下文中描述的所有功能,但是不会阻止多个线程的同时访问;类 ostream 是一个“包装器”类,它围绕 unsafe_ostream 的每个相应成员函数实施互斥锁以确保多线程安全性。单纯使用多线程安全的类不能担保您的应用程序的多线程安全行为。有关在协作的线程之间共享 iostream 对象的完整信息,请参见《C++ Library Reference》中的第 4 章 "Using Classic iostream in a Multithreaded Environment"。
将 sbufp 指向的 streambuf 与流相关联并初始化 ios 状态。
不执行初始化。
将 sbufp 指向的 streambuf 与 osw 相关联并完全初始化 osw。
与 ostr 关联的 streambuf 将变为与 osw 关联并且构造函数将完全初始化 osw。
注意:必须初始化类 ostream_withassign 的本地对象。
对于向流输出宽字符的所有操作,如果它们遇到在当前区域设置下没有多字节表示形式的宽字符,则它们会设置 ios::failbit 并停止输出。它们都调用 opfx()。
执行所有插入操作通用的设置。如果 ostr 的错误状态是非零值,则 opfx 立即返回零。如果流绑定到 ostr(请参见 ios3CC4() 中的 tie),则会刷新绑定的流。如果遇到任何错误情况,函数 opfx 将返回零,否则将返回非零值。用户定义的插入器应当从调用 opfx 开始。
在插入操作结束时执行后续操作。如果设置了 ios::unitbuf,则会刷新流。如果设置了 ios::stdio,则会刷新 stdout 和 stderr。(请参见 ios(3CC4)。)它没有返回值。所有预定义的插入器都调用 osfx,但是无格式的输出函数不调用它。用户定义的插入器在返回前都应当调用 osfx。
有格式的输出函数调用 opfx()。如果它返回零,则不会发生进一步的操作。这些函数在返回前也调用 osfx()(如果 opfx() 成功)。
如果 ostr.opfx() 返回非零值,则会将可以从 sbufp 指向的 streambuf 提取的所有字符插入到 ostr 中。不会执行填充。返回对 ostr 的引用。您可以使用此函数有效地复制流,但是应当确保流未绑定。例如:
#include <iostream.h> main() { // copy cin to cout cin.tie(0); cout.tie(0); cout << cin.rdbuf(); // see ios(3CC4) for rdbuf return 0; }
如果 ostr.opfx(0) 返回非零值,则会将表示 x 的字符插入到 ostr 中。如果 opfx 返回零,则不会采取操作。遇到的任何错误都将记录在 ostr 的错误状态中。这些函数始终返回对 ostr 的引用。用户编写的函数应当采用格式
ostream& operator<< (ostream&, SomeType)
并且应当遵循这些原则。
x 的类型和 ostream 的格式状态(请参见 ios(3CC4))决定了转换和插入的细节。除了 width 变量在每次有格式的插入之后会重置为零之外,这些函数不更改 ostream 的状态。预定义的有格式插入器及其转换规则如下所述:
将字符 x 插入到 ostr 中且不执行转换。
将宽字符转换为多字节表示形式并插入到流中。如果宽字符在当前区域设置下没有多字节表示形式,则会设置 ios::failbit 并停止。
该表示形式由没有前导零的一个“数位”序列构成。如果设置了 ios::oct,则数位和转换是八进制的;如果设置了 ios::hex,则为十六进制的;如果设置了 ios::dec 或者未设置其中任何一个,则为十进制的。对于十进制转换,如果 x 是正数并且设置了 ios::showpos,则会有一个前导加号 ('+');如果 x 是负数,则会有一个前导减号 ('-')。八进制和十六进制转换被视为无符号的,不会包括符号。如果设置了 ios::showbase,则对于八进制转换有一个前导 '0',对于十六进制转换有一个前导 "0x'' 或 "0X'',具体取决于是否设置了 ios::uppercase。
x 的值将根据 ostr 中 precision、width、ios::scientific、ios::fixed 和 ios::uppercase 的当前值进行转换。请参见 ios (3CC4) 。
此表示形式表示的字符序列从 x 指向的字符开始,直到但不包括第一个空 (0) 字符。
在数组中插入宽字符的多字节表示形式,直至遇到第一个 0 宽字符。如果遇到在当前区域设置下没有多字节表示形式的宽字符,则会设置 ios::failbit 并停止。注意:填充基于以字符为单位而非以字节为单位测量的字段宽度。在当前实现中,填充字符始终是一个单字节。
指针的转换情况与它是 int 并且设置了 ios::showbase 和 ios::hex 时相同。
这些操作不调用 opfx() 或 osfx()。
将字符 c 插入到 ostr 中。如果操作失败则会设置错误状态。始终返回对 ostr 的引用。
将宽字符的多字节表示形式放置到 ostr 中。如果操作失败则会设置错误状态。始终返回对 ostr 的引用。
从 ptr 指向的 char 数组的开头开始,将恰好 len 个字符插入到 ostr 中。如果操作失败则会设置错误状态。始终返回对 ostr 的引用。
将 wptr 指向的确切数目的宽字符的多字节表示形式提取到 ostr 中。
这些函数处理指向与 ostream 关联的 streambuf 的 put 指针。有关完整论述,请参见 sbufpub(3CC4)。多字节输入操作可能会导致 streambuf 的 get 指针不同于 tellg() 报告的值,但是在 istream 而非 streambuf 上执行的查找仍将与 istream 上的所有操作正确协调。
这些函数设置 put 指针的位置;它们返回对 ostr 的引用。
此函数返回 put 指针的当前位置。
这将导致刷新存储到关联 streambuf 中的任何字符;例如,写入到输出文件。它返回对 ostr 的引用。
操纵符可以明确地用作插入的或提取的对象,但许多仅更改流的状态。有关更多信息,请参见 manip(3CC4) 和 ios(3CC4)。预定义了多个与 ostreams 一起使用的操纵符。
这等效于调用 manip(ostr)。
它将 ostr 的转换基设置为 10。
它将 ostr 的转换基设置为 8。
它将 ostr 的转换基设置为 16。
它通过插入一个换行符并刷新 ostr 来结束一个行。
它通过将空 (0) 字符插入 ostr 中来结束一个字符。
这等效于调用 ostr.flush()。
ios (3CC4) 、 ios.intro (3CC4) 、 manip (3CC4) 、 sbufpub (3CC4)
《C++ Library Reference》中的第 3 章 "The Classic iostream Library" 和第 4 章 "Using Classic iostreams in a Multithreaded Environment"。