C++ *stream | istream / ostream / iostream 详解
注:本文为 “C++ *stream” 相关文章合辑。
英文引文,机翻未校。
中文引文,略作重排,未整理去重。
如有内容异常,请看原文。
Understanding the Utility of Iostreams in C++
理解 C++ 中 iostream 的用途
By Manoj Debnath
February 27, 2020
The iostream classes are the first library classes we encounter when we begin with C++. The primary services that we deal with these classes is solving general I/O problems. After all, this is what the name apparently means. But the beauty is that it represents standard I/O, files, and even blocks of memory and they look the same with one interface. The article explores some of the facets of this incredible class with simple example.
当我们开始学习 C++ 时,iostream 类是我们遇到的第一个库类。我们使用这些类的主要目的是解决一般的输入输出问题。毕竟,这正是它的名字所表达的含义。然而,它的美妙之处在于,它不仅代表标准输入输出和文件,甚至还可以表示内存块,而且所有这些都通过一个统一的接口来实现。本文通过一个简单的例子探讨了这个令人惊叹的类的一些方面。
What is iostream in C++?
C++ 中的 iostream 是什么?
The C++ language deals with I/O a bit differently than other languages. It is handled by a family of types prescribed in the standard library. The I/O to and from device files, consoles, and in-memory I/O, such as from string, are all handled by these types. The primary functions defined are read/write operations of the built-in types. Therefore, the I/O stream library provides formatted as well as unformatted buffered I/O of text as well as numeric values.
C++ 语言在处理输入输出时与其他语言有所不同。它是通过标准库中定义的一系列类型来处理的。这些类型负责处理来自设备文件、控制台以及内存中的输入输出(例如来自 string 的数据)。其主要功能是执行内置类型的读写操作。因此,输入输出流库提供了对文本和数值的格式化以及非格式化的缓冲输入输出。
What is a Stream in C++?
C++ 中的流是什么?
When a sequence of bytes flows from one interface to another, it can be called a stream. This sequence of bytes represents information that may be further processed or used as is, depending upon the context. When the flow of bytes sequence is main memory inbound, such as from devices like a keyboard, disk, or network connection, it is called an input operation. And, when the flow of bytes is main memory outbound to a device such as printer, disk, network connection, or display screen, it is called an output operation. The sequence of bytes can have different meanings depending upon the context. It can represent characters, graphical images, raw data, audio/video information, or any other type depending upon the context of use.
当一系列字节从一个接口流向另一个接口时,可以将其称为一个 stream(流)。这一系列字节表示的信息可以根据上下文进一步处理或直接使用。当字节序列流入主内存时,例如来自键盘、磁盘或网络连接等设备,这被称为 input operation(输入操作)。而当字节序列从主内流出到打印机、磁盘、网络连接或显示器等设备时,这被称为 output operation(输出操作)。字节序列的含义可以根据上下文有所不同,它可以表示字符、图形图像、原始数据、音频/视频信息,或者根据使用上下文的任何其他类型。
The I/O mechanism must be able to transfer the sequence of bytes in a consistent and efficient manner. But, the problem is that the devices associated with the I/O are often slow in operation. For example, the mechanical rotation of a disk, input coming from keyboard strokes, or sequence of bytes from remote interface require considerably more time than the time required by the processor to process the data. Therefore, to mitigate the time gap so that it does not lag the overall performance of the I/O operation, the C++ stream library classes are fine tuned for optimal performance.
输入输出机制必须能够以一致且高效的方式传输字节序列。然而,问题在于与输入输出相关的设备通常操作速度较慢。例如,磁盘的机械旋转、来自键盘按键的输入,或者来自远程接口的字节序列,都需要比处理器处理数据所需的时间多得多。因此,为了减少这种时间差,以免拖慢整个输入输出操作的性能,C++ 的流库类经过了优化,以实现最佳性能。
Another problem is that data usually comes in different formats. Some come as an unformatted I/O format, which require low-level I/O processing, and some comes in formatted I/O format, which require high-level I/O capabilities. The unformatted I/O specified by sequence of bytes requires processing of individual bytes during its transfer from device to memory or memory to device. Such data often comes in high volume and require fast processing capabilities. In formatted I/O, the sequence of bytes forms a unit of meaningful combination of bytes such as characters, floating-point numbers, integers, strings, or any other user-defined types. Handling I/O with such data units is convenient but inefficient, especially when they come in high volume. The standard C++ stream library supports both the format and does both high- and low-level I/O processing, respectively.
另一个问题是,数据通常以不同的格式出现。有些是以非格式化的输入输出格式出现,需要进行低级输入输出处理;而有些是以格式化的输入输出格式出现,需要高级输入输出功能。以字节序列指定的非格式化输入输出在从设备传输到内存或从内存传输到设备时,需要逐字节处理。这种数据通常数据量很大,需要快速处理能力。在格式化输入输出中,字节序列形成了一个有意义的字节组合单元,例如字符、浮点数、整数、字符串或任何其他用户定义的类型。使用这种数据单元进行输入输出操作虽然方便,但效率较低,尤其是在数据量很大时。标准 C++ 流库同时支持这两种格式,并分别进行高级和低级输入输出处理。
Character Sets
字符集
Previously, the C++ library used to support only input and output of chars which carried only one byte of information, such as those we find with the ASCII (American Standard Code for information Interchange) (8 - bit/1 - byte) character set. But later, it introduced Unicode characters, which represent extensive international character sets, the I/O capabilities of C++ encompassed them within its framework. For example, the type wchar_t (4 - byte/32 - bit) is a later inclusion and can store Unicode characters. Also, C++11 introduced other types, such as char16_t and char32_t, to represent character types that require explicit sizes. The stream classes were redesigned as specialized templates for dealing with char and wchar_t, respectively.
以前,C++ 库仅支持单字节信息的字符输入输出,例如我们在 ASCII(美国信息交换标准代码)(8 位/1 字节)字符集中所见到的字符。但后来,它引入了 Unicode 字符,这些字符代表广泛的国际字符集,C++ 的输入输出功能将其纳入了其框架中。例如,类型 wchar_t(4 字节/32 位)是后来加入的,可以存储 Unicode 字符。此外,C++11 引入了其他类型,如 char16_t 和 char32_t,以表示需要明确大小的字符类型。流类被重新设计为专门的模板,分别用于处理 char 和 wchar_t。
Stream Classes and Objects
流类和对象
A C++ program includes a header to avail the basic service required for all stream I/O operations. There are four objects defined by iostream: cin, cout, cerr, and clog that correspond to the standard input stream, standard output stream, standard error stream (unbuffered), and standard error stream (buffered), respectively. Each of them provides both formatted and unformatted I/O services.
C++ 程序通过包含 头文件来获取所有流输入输出操作所需的基本服务。iostream 定义了四个对象:cin、cout、cerr 和 clog,分别对应标准输入流、标准输出流、标准错误流(未缓冲)和标准错误流(缓冲)。它们每一个都提供格式化和非格式化的输入输出服务。
There is another header, called , which provides parameterized stream manipulators for performing formatted I/O such as setw, setbase, setprecision, setfill, setiosflags, and more.
另外还有一个名为 的头文件,它提供了用于执行格式化输入输出的参数化流操纵器,例如 setw、setbase、setprecision、setfill、setiosflags 等。
The header is particularly used in association with file processing and provides services for file I/O.
头文件特别用于文件处理,提供文件输入输出服务。
The library stream classes form hierarchy as follows. Figure 1 gives you a quick idea on some of their traits.
库流类形成了如下层次结构。图 1 为您快速展示了它们的一些特征。
Figure 1: The library stream classes’ hierarchy
图 1:库流类的层次结构
-
The ios_base class is the base class for all stream classes of the standard I/O library. It defines common properties of all stream objects, independent of their character type, such as functions for state and format flags.
ios_base 类是标准输入输出库中所有流类的基类。它定义了所有流对象的通用属性,这些属性与其字符类型无关,例如用于状态和格式标志的函数。
-
The basic_ios is a template class derived from ios_base. It defines a stream component independent of input or output, but depends on character types and their traits. They provide the buffer definition, such as the object from the template class basic_streambuf. They are used for the read/write scheme.
basic_ios 是从 ios_base 派生的模板类。它定义了一个与输入或输出无关的流组件,但依赖于字符类型及其特征。它们提供了缓冲区定义,例如来自模板类 basic_streambuf 的对象。它们用于读写方案。
-
The basic_istream and basic_ostream are template classes derived from basic_ios. They define the objects used for read and write operations, respectively. These classes too are parameterized with character types and its traits.
basic_istream 和 basic_ostream 是从 basic_ios 派生的模板类。它们分别定义了用于读取和写入操作的对象。这些类也以字符类型及其特征为参数。
-
The basic_streambuf is the core of the I/O stream library. They provide the interface for read and write operations of the stream.
basic_streambuf 是输入输出流库的核心。它们提供了流的读取和写入操作的接口。
We accept input via descendants of the istream classes and output via descendants of the ostream classes. The iostream classes combine both and provide an object to do input as well as output. Apart from these, the iostream library provides classes for ifstream file input, ofstream for file output, and fstream for both input as well as output operation on files. Similarly, there are classes, such as istringstream, ostringstream, and stringstream, for I/O operation with string classes. They almost have a same interface whether we work with a file, standard I/O, memory, or string object. The stream classes discussed above are the templatized versions to leverage generic type I/O operation.
我们通过 istream 类的派生类接收输入,通过 ostream 类的派生类进行输出。iostream 类结合了两者,提供了一个既可以输入也可以输出的对象。除了这些,iostream 库还提供了用于文件输入的 ifstream 类、文件输出的 ofstream 类,以及用于文件输入输出操作的 fstream 类。同样,还有用于与字符串类进行输入输出操作的类,例如 istringstream、ostringstream 和 stringstream。无论我们是处理文件、标准输入输出、内存还是字符串对象,它们几乎都具有相同的接口。上述讨论的流类是模板化版本,用于实现通用类型的输入输出操作。
A Quick Example
一个快速示例
Here is a quick demonstration of object input/output by overloading ostream and istream operators. The properties of the rudimentary Date class object get inserted and extracted conveniently using stream operators.
下面是一个通过重载 ostream 和 istream 运算符来实现对象输入输出的快速示例。通过使用流运算符,可以方便地插入和提取基础的 Date 类对象的属性。
#ifndef DATE_H #define DATE_H #include class Date { int day , month , year; // 私有成员变量,用于存储日期的天、月、年 public: Date(); // 构造函数声明,用于初始化日期对象 friend std::ostream& operator> 运算符,用于输入 Date 对象 }; #endif // DATE_H #include "date.h" #include #include #include using namespace std; Date::Date() { time_t today = time(0); // 获取当前时间 tm *lt = localtime(&today); // 将时间转换为本地时间结构 year = lt->tm_year + 1900; // 设置年份(tm_year 是从 1900 年开始的年数) month = lt->tm_mon + 1; // 设置月份(tm_mon 是从 0 开始的月份,需要加 1) day = lt->tm_mday; // 设置日期 } ostream& operator os is d.day d.month d.year; // 从输入流中读取日期的天、月、年 return is; // 返回输入流对象 } #include Date d; // 创建一个 Date 对象,默认为当前日期 Date d2; // 创建另一个 Date 对象 cout class ios_base { public: // ios_base status methods bool good() const; // true iff no error flag is set bool eof() const; // true iff stream is at end of file bool fail() const; // true iff badbit or failbit are set bool bad() const; // true if badbit is set operator void*() const; // null pointer if fail(), non-null otherwise void clear(iostate newstate = goodbit); // sets state to newstate void setstate(iostate addstate); // adds addstate to existing state enum iostate { goodbit = 0x0000, // everything's ok eofbit = 0x0001, // stream is at end of file failbit = 0x0002, // last I/O operation failed badbit = 0x0004 // serious error, stream unusable }; protected: unsigned long state; // stores status bits }; } public: bool good() const; // true if no error flag is set bool eof() const; // true if eofbit is set bool fail() const; // true if badbit or failbit are set bool bad() const; // true if badbit is set operator void*() const; // null pointer if fail(), non-null otherwise void clear(iostate newstate = goodbit); // sets state to newstate void setstate(iostate addstate); // adds addstate to existing state enum iostate { goodbit = 0x0000, // everything's ok eofbit = 0x0001, // stream is at end of file failbit = 0x0002, // last I/O operation failed badbit = 0x0004 // serious error, stream unusable }; protected: unsigned long state; // stores status bits }; std::cout public: fmtflags flags() const; // returns current flags fmtflags flags(fmtflags newflags); // sets flags to newflags fmtflags setf(fmtflags setbits); // sets specified flags fmtflags setf(fmtflags setbits, fmtflags mask); // sets flags in mask fmtflags unsetf(fmtflags unsetbits); // clears specified flags enum fmtflags { boolalpha = 0x0001, // read/write bool values in alphabetic left = 0x0002, // left-justify output right = 0x0004, // right-justify output internal = 0x0008, // prefix left..fill..number right skipws = 0x0010, // skip white space before extraction dec = 0x0020, // decimal hex = 0x0040, // hexadecimal oct = 0x0080, // octal showbase = 0x0100, // show base indicator on output showpoint = 0x0200, // show decimal point for fixed point output showpos = 0x0400, // force show of sign for positive numbers fixed = 0x0800, // force decimal notation for float scientific = 0x1000, // force scientific notation for float unitbuf = 0x2000, // flush buffer after each insertion uppercase = 0x4000 // use upper case indicators for hex and e }; protected: unsigned long flags; // stores flag bits }; public: char fill(char fillch); // sets fill character int precision() const; // returns precision value int precision(int val); // sets precision value int width() const; // returns width value int width(int val); // sets width value protected: int width_value; // initialized to 0 int precision_value; // initialized to 0 char fill_character; // initialized to ' ' }; public: streambuf* rdbuf(); // returns ptr to stream's streambuf object ostream* tie(); // returns ptr to the tied ostream ostream* tie(ostream*); // ties current stream to specified ostream static bool sync_with_stdio(bool sync = true); // sync with C standard I/O protected: streambuf* streambuffer; // pointer to a streambuf object ostream* tied_ostream; // pointer to an ostream object }; public: enum open_mode { in = 0x0001, // open file for input out = 0x0002, // open file for output ate = 0x0004, // seek to end when file is opened app = 0x0008, // open file in append mode trunc = 0x0010, // truncate the file if it exists binary = 0x0020 // open file in binary mode }; enum seek_dir { beg = 0x0100, // seek relative to beginning of file cur = 0x0200, // seek relative to current position end = 0x0400 // seek relative to end of file }; protected: unsigned long mode; // stores open and seek mode bits }; return flags; } ios_base::fmtflags ios_base::flags(ios_base::fmtflags newflags) { ios_base::fmtflags oldflags = flags; flags = newflags; return oldflags; } ios_base::fmtflags ios_base::setf(ios_base::fmtflags setbits) { ios_base::fmtflags oldflags = flags; flags |= setbits; return oldflags; } ios_base::fmtflags ios_base::setf(ios_base::fmtflags setbits, ios_base::fmtflags mask) { ios_base::fmtflags oldflags = flags; flags = (flags & ~mask) | (setbits & mask); return oldflags; } ios_base::fmtflags ios_base::unsetf(ios_base::fmtflags unsetbits) { ios_base::fmtflags oldflags = flags; flags &= ~unsetbits; return oldflags; } char ios_base::fill(char newfill) { char oldfill = fill_character; fill_character = newfill; return oldfill; } int ios_base::precision() const { return precision_value; } int ios_base::precision(int val) { int oldprecision = precision_value; precision_value = val; return oldprecision; } int ios_base::width() const { return width_value; } int ios_base::width(int val) { int oldwidth = width_value; width_value = val; return oldwidth; } class istream : public ios_base { public: friend istream& operator(istream&, char&); friend istream& operator(istream&, int); friend istream& operator>>(istream&, long); friend istream& operator>>(istream&, unsigned char); friend istream& operator>>(istream&, unsigned int); friend istream& operator>>(istream&, unsigned long); friend istream& operator>>(istream&, float); friend istream& operator>>(istream&, double); friend istream& operator>>(istream&, long double); friend istream& operator>>(istream&, char*); void get(char&); char get(); char peek(); // predefined object cin; }; }
Class ostream
ostream 类
namespace std { class ostream : public ios_base { public: friend ostream& operator public: ifstream* open(const char* filename, ios_base::open_mode mode = ios_base::in); ifstream* close(); }; public: ofstream* open(const char* filename, ios_base::open_mode mode = ios_base::out | ios_base::trunc); ofstream* close(); }; os class ios_base { public: // ios_base status methods bool good() const; // true if no error flag is set bool eof() const; // true if stream is at end of file bool fail() const; // true if badbit or failbit are set bool bad() const; // true if badbit is set operator void*() const; // null pointer if fail(), non-null otherwise void clear(iostate newstate = goodbit); // sets state to newstate void setstate(iostate addstate); // adds addstate to existing state enum iostate { goodbit = 0x0000, // everything's ok eofbit = 0x0001, // stream is at end of file failbit = 0x0002, // last I/O operation failed badbit = 0x0004 // serious error, stream unusable }; protected: unsigned long state; // stores status bits unsigned long flags; // stores mode bits unsigned long mode; // stores flag bits int width_value; // initialized to 0 int precision_value; // initialized to 0 char fill_character; // initialized to ' ' streambuf* streambuffer; // pointer to a streambuf object // plus other data, such as specifying tied streams }; } public: bool good() const; // true if no error flag is set bool eof() const; // true if eofbit is set bool fail() const; // true if badbit or failbit are set bool bad() const; // true if badbit is set operator void*() const; // null pointer if fail(), non-null otherwise void clear(iostate newstate = goodbit); // sets state to newstate void setstate(iostate addstate); // adds addstate to existing state enum iostate { goodbit = 0x0000, // everything's ok eofbit = 0x0001, // stream is at end of file failbit = 0x0002, // last I/O operation failed badbit = 0x0004 // serious error, stream unusable }; protected: unsigned long state; // stores status bits }; std::cout public: fmtflags flags() const; // returns current flags fmtflags flags(fmtflags newflags); // sets flags to newflags fmtflags setf(fmtflags setbits); // sets specified flags fmtflags setf(fmtflags setbits, fmtflags mask); // sets flags in mask fmtflags unsetf(fmtflags unsetbits); // clears specified flags enum fmtflags { boolalpha = 0x0001, // read/write bool values in alphabetic left = 0x0002, // left-justify output right = 0x0004, // right-justify output internal = 0x0008, // prefix left..fill..number right skipws = 0x0010, // skip white space before extraction dec = 0x0020, // decimal hex = 0x0040, // hexadecimal oct = 0x0080, // octal showbase = 0x0100, // show base indicator on output showpoint = 0x0200, // show decimal point for fixed point output showpos = 0x0400, // force show of sign for positive numbers fixed = 0x0800, // force decimal notation for float scientific = 0x1000, // force scientific notation for float unitbuf = 0x2000, // flush buffer after each insertion uppercase = 0x4000 // use upper case indicators for hex and e }; protected: unsigned long flags; // stores flag bits }; public: char fill(char fillch); // 设置填充字符 int precision() const; // 返回精度值 int precision(int val); // 设置精度值 int width() const; // 返回宽度值 int width(int val); // 设置宽度值 protected: int width_value; // 初始化为 0 int precision_value; // 初始化为 0 char fill_character; // 初始化为空格 }; public: streambuf* rdbuf(); // 返回指向流的 streambuf 对象的指针 ostream* tie(); // 返回指向绑定的 ostream 的指针 ostream* tie(ostream*); // 将当前流绑定到指定的 ostream static bool sync_with_stdio(bool sync = true); // 与 C 标准 I/O 同步 protected: streambuf* streambuffer; // 指向 streambuf 对象的指针 ostream* tied_ostream; // 指向 ostream 对象的指针 }; public: enum open_mode { in = 0x0001, // 以输入模式打开文件 out = 0x0002, // 以输出模式打开文件 ate = 0x0004, // 打开文件时定位到文件末尾 app = 0x0008, // 以追加模式打开文件 trunc = 0x0010, // 如果文件存在则截断文件 binary = 0x0020 // 以二进制模式打开文件 }; enum seek_dir { beg = 0x0100, // 从文件开头开始定位 cur = 0x0200, // 从当前位置开始定位 end = 0x0400 // 从文件末尾开始定位 }; protected: unsigned long mode; // 存储打开和定位模式的位 }; return flags; } ios_base::fmtflags ios_base::flags(ios_base::fmtflags newflags) { ios_base::fmtflags oldflags = flags; flags = newflags; return oldflags; } ios_base::fmtflags ios_base::setf(ios_base::fmtflags setbits) { ios_base::fmtflags oldflags = flags; flags |= setbits; return oldflags; } ios_base::fmtflags ios_base::setf(ios_base::fmtflags setbits, ios_base::fmtflags mask) { ios_base::fmtflags oldflags = flags; flags = (flags & ~mask) | (setbits & mask); return oldflags; } ios_base::fmtflags ios_base::unsetf(ios_base::fmtflags unsetbits) { ios_base::fmtflags oldflags = flags; flags &= ~unsetbits; return oldflags; } char ios_base::fill(char newfill) { char oldfill = fill_character; fill_character = newfill; return oldfill; } int ios_base::precision() const { return precision_value; } int ios_base::precision(int val) { int oldprecision = precision_value; precision_value = val; return oldprecision; } int ios_base::width() const { return width_value; } int ios_base::width(int val) { int oldwidth = width_value; width_value = val; return oldwidth; } class istream : public ios_base { public: friend istream& operator(istream&, char&); friend istream& operator(istream&, int); friend istream& operator(istream&, long); friend istream& operator(istream&, unsigned char); friend istream& operator(istream&, unsigned int); friend istream& operator(istream&, unsigned long); friend istream& operator(istream&, float); friend istream& operator(istream&, double); friend istream& operator(istream&, long double); friend istream& operator(istream&, char*); void get(char&); char get(); char peek(); // 预定义对象 cin; }; }
Class ostream
ostream 类
namespace std { class ostream : public ios_base { public: friend ostream& operator public: ifstream* open(const char* filename, ios_base::open_mode mode = ios_base::in); ifstream* close(); }; public: ofstream* open(const char* filename, ios_base::open_mode mode = ios_base::out | ios_base::trunc); ofstream* close(); }; os public: Test ( int a = 0 , int b = 0 ) { this - a = a; this - b = b; } int a; int b; }; int main() { Test t ( 100 , 50 ); printf ( "%???" , t ); // 输出格式不明确 scanf ( "%???" , t ); // 输入格式不明确 cout ofstream myfile ( "c:\\1.txt" , ios::out | ios::trunc , 0 ); myfile ofstream myfile ( "c:\\1.txt" , ios::app , 0 ); if ( !myfile ) // 或者写成 myfile.fail() { cout ofstream myfile; myfile.open ( "c:\\1.txt" , ios::out | ios::app , 0 ); if ( !myfile ) // 或者写成 myfile.fail() { cout ifstream myfile; myfile.open ( "c:\\1.txt" , ios::in , 0 ); if ( !myfile ) { cout content += ch; cout.put ( ch ); // cout fstream myfile; myfile.open ( "c:\\1.txt" , ios::out | ios::app , 0 ); if ( !myfile ) { cout cout cout.put ( ch ); } myfile.close(); system ( "pause" ); } char *name = "www.cppblog.com/andxie99"; int arraysize = strlen ( name ) + 1; istrstream is ( name , arraysize ); char temp; is temp; cout int arraysize = 100; char *pbuffer = new char [ arraysize ]; ostrstream ostr ( pbuffer , arraysize , ios::out ); ostr stringstream ostr ( "ccc" ); ostr.put ( 'd' ); ostr.put ( 'e' ); ostr stringstream sstr; //--------int 转 string----------- int a = 100; string str; sstr int a; cin a; cout cout cout int a; cin a; cout cout cout int a; cin a; cout int a; while ( 1 ) { cin a; if ( !cin ) // 条件可改写为 cin.fail() { cout cout ifstream myfile ( "c:\\1.txt" , ios_base::in , 0 ); if ( myfile.fail() ) { cout char ch; while ( myfile.get ( ch ) ) { cout cout char str[] = "Hello C++"; std::cout char name[50]; std::cout char str[] = "Unable to read...."; std::clog char str[] = "Unable to read...."; std::cerr int i = 0; std::wcout int i = 0; std::cout // ... } public: A(int a) : _a(a) {} operator bool() { if (_a 10) return false; else return true; } private: int _a; }; int main() { A a1(20); A a2(1); cout extern istream cin; extern ostream cout; extern ostream cerr; extern ostream clog; extern wistream wcin; extern wostream wcout; extern wostream wcerr; extern wostream wclog; } // std #include _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Template class basic_ostream. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits public: // Types (inherited from basic_ios): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; // Non-standard Types: typedef basic_streambuf