The C++ stream-based I/O library allows you to perform I/O operations without having to know details about the target to or source from which you are streaming. A stream’s target or source could be a string, a file, a memory buffer, and so on.
Input and Output with Streams
The stream classes provided by the Standard Library are organized in a hierarchy and a set of headers, as shown in Figure 5-1.
Figure 5-1.
The hierarchy
of stream-related classes
More accurately, the library defines templates called basic_ios, basic_ostream, basic_istringstream, and so on, all templated on a character type. All classes in the hierarchy, except ios_base, are typedefs for these templated classes with char as template type. For example, std::ostream is a typedef for std::basic_ostream<char>. There are equivalent typedefs for the wchar_t character type called wios, wostream, wofstream, and so on. The remainder of this chapter only uses the char typedefs shown in Figure 5-1.
In addition to the headers in the figure, there is also <iostream>. Somewhat confusingly, this does not really define std::iostream itself, because this is done by <istream>. Instead, <iostream> includes <ios>, <streambuf>, <istream>, <ostream>, and <iosfwd>, while itself adding the standard input and output streams (w)cin, (w)cout, (w)cerr, and (w)clog. The latter two are intended for output of errors and logging information, respectively. Their destinations are implementation specific.
The library also provides the std::basic_streambuf, basic_filebuf, and basic_stringbuf templates and their various typedefs, plus istreambuf_iterator and ostreambuf_iterator. These are, or work on, stream buffers and are the basis for the implementation of other stream classes, such as ostream, ifstream, and so on. They are briefly discussed toward the end of this chapter.
The header <iosfwd> contains forward declarations of all the standard I/O library types. It is useful to include it in other header files without having to include the complete template definitions of all the types you require.
Helper Types <ios>
The following helper types
are defined in <ios>:
Type | Description |
---|---|
std::streamsize
| A typedef for a signed integral type used to represent the number of characters transferred during an I/O operation, or to represent the size of an I/O buffer. |
std::streamoff
| A typedef for a signed integral type used to represent an offset into a stream. |
std::fpos
| A class template containing an absolute position in a stream and a conversion operator to convert it into a streamoff. Certain arithmetic operations are supported: a streamoff can be added to or subtracted from an fpos, resulting in an fpos (using +, -, +=, or -=), and two fpos objects can be compared (using == or !=) or subtracted, resulting in a streamoff (using -). Predefined typedefs are provided: std::streampos and wstreampos for the character types char and wchar_t.
|
std::ios_base <ios>
The
ios_base class
, defined in <ios>, is the base class for all input and output stream classes. It keeps track of formatting options and flags to manipulate how data is read and written. The following methods are provided:
Method | Description |
---|---|
precision()
precision(streamsize)
| Returns the precision for floating-point I/O, or changes it while returning the old one. The semantics of the precision depend on which floatfield formatting flag is set (see Table 5-1 and Table 5-2). If either fixed or scientific is set, the precision specifies exactly how many digits to show after the decimal separator, even if this means adding trailing zeros. If neither is set, then it denotes the maximum number of digits to show, counting both the digits before and after the decimal separator (no zeros are added in this case). And if both are set, the precision is ignored. |
width()
width(streamsize)
| Returns the width of the next field, or changes it while returning the old one. This width specifies the minimum number of characters to output with certain I/O operations. To reach this minimum, fill characters (explained later) are added. Only has an effect on the next I/O operation. |
getloc()
imbue(locale)
| Returns the locale used during I/O, or changes it while returning the old one. See Chapter 6 for details on locales. |
flags()
flags(fmtflags)
| Returns the currently set formatting flags, or replaces the current flags while returning the old ones. Table 5-1 lists all available fmtflags flags, which can be combined bitwise. |
setf(fmtflags)
unsetf(fmtflags)
| Sets or unsets individual flags without touching others. The flags prior to the update are returned. |
setf(fmtflags flags,
fmtflags mask)
| Sets flags while unsetting others in a group, specified as a mask. Table 5-2 lists the predefined masks. For example, setf(right | fixed, adjustfield | floatfield) sets the right and fixed flags while unsetting the left, internal, and scientific flags.
|
It is also possible to modify flags by streaming I/O manipulators, discussed in the next section.
Table 5-1.
std::ios_base::fmtflags Formatting Flags
Defined in <ios>
Flag | Description |
---|---|
boolalpha
| Use true and false instead of 1 and 0 for Boolean I/O. |
left,
right,internal
| Output is left aligned with fill characters added to the right, or right aligned with padding on the left, or adjusted by padding in the middle. The third flag, internal, works for numerical and monetary values, with the designated padding point being between the value and any of its prefixes: a sign, numerical base, and/or currency symbol. Otherwise, internal is equivalent to right. The results of the different alignment options are shown in the example section. |
scientific, fixed
| If neither of these flags is set, use default notation for floating-point I/O (for instance: 0.0314). Otherwise, use scientific (3.140000e-02) or fixed notation (0.031400). If both are combined, scientific | fixed, use hexadecimal floating-point notation (0x1.013a92p-5). |
dec, oct, hex
| Use a decimal, octal, or hexadecimal base for integer I/O. |
showbase
| For integer I/O, write or expect the base prefix as specified with dec, oct, or hex. When performing monetary I/O, std::put_money() prefixes values with the locale-dependent currency symbol, and std::get_money() requires a currency symbol prefix. |
showpoint
| Always use a locale-dependent decimal separator character for floating-point I/O, even if the decimal part is zero. |
showpos
| Use a + character for non-negative numeric I/O. |
skipws
| Instructs all formatted input operations (explained later) to skip leading whitespace. |
unitbuf
| Forces the output to be flushed after each output operation. |
uppercase
| Instructs floating-point and hexadecimal integer output operations to use uppercase letters instead of lowercase ones.
|
Table 5-2.
std::ios_base::fmtflags Masks Defined
in <ios>
Flag | Description |
---|---|
basefield
|
dec | oct | hex
|
adjustfield
|
left | right | internal
|
floatfield
|
scientific | fixed
|
I/O Manipulators <ios>, <iomanip>
Manipulators
allow you to change flags using operator<< and operator>> instead of flags(fmtflags) or setf().
The <ios> header defines I/O manipulators in the global std scope for all the flags defined in Table 5-1: std::scientific, std::left, and so on. For flags that are part of a mask defined in Table 5-2, the I/O manipulator uses that mask. For example, std::dec actually calls ios_base::setf(dec, basefield).
For boolalpha, showbase, showpoint, showpos, skipws, uppercase, and unitbuf, negative manipulators are available as well, which have the same name but are prefixed with no: for example, std::noboolalpha.
In addition to std::fixed and scientific, there are also std::hexfloat (scientific | fixed) and std::defaultfloat (no floatfield flags set) manipulators.
Additionally, the <iomanip> header defines the following manipulators:
Manipulator | Description |
---|---|
setiosflags(fmtflags)
resetiosflags(fmtflags)
| Sets/unsets the given fmtflags. |
setbase(int)
| Changes the base used for integer I/O. A value other than 16 (hex), 8 (oct), or 10 (dec) sets the base to 10. |
setfill(char)
| Changes the fill character. See the example later. |
setprecision(int)
| Changes the number of decimal places for floating-point output as if set with ios_base::precision(). |
setw(int)
| Sets the width of the next field. See the example. |
get_money(m&, bool=false)
put_money(m&, bool=false)
| Reads or writes a monetary value. If the Boolean is true, use international currency strings (e.g. "USD "); otherwise use currency symbols (e.g. "$"). The type of m can be either std::string or long double. See Chapter 6 for more details on monetary formatting. |
get_time(tm*, char*)
put_time(tm*, char*)
| Reads or writes a date/time. The formatting is the same as for std::strftime(), discussed in Chapter 2. |
quoted()
| Reads or writes quoted strings and properly handles embedded quotes. An example of this manipulator is given in the section on how to implement your own operator<< and operator>> later in this chapter.
|
Example
This code snippet additionally needs <locale>:
On an American system, the output is as follows:
Left: $1.23__
Right: __$1.23
Internal: 0x___7b
std::ios <ios>
The
ios class defined
in <ios> inherits from ios_base and provides a number of methods to inspect and modify the state of a stream, which is a bitwise combination of the state flags listed in Table 5-3.
Table 5-3.
std::ios_base::iostate State Constants Defined
in <ios>
iostate | Description |
---|---|
goodbit
| The stream is not in any error state. No bits are set: i.e. the state is 0. |
badbit
| The stream is in an unrecoverable error state. |
failbit
| An input or output operation failed. For example, reading a numerical value into an integer could cause the failbit to be set if the numerical value overflows the integer. |
eofbit
| The stream is at its end. |
The following state-related methods
are provided:
Method | Description |
---|---|
good()
eof()
bad()
fail()
| Returns true if, respectively, the badbit, failbit, and eofbit are not set, the eofbit is set, the badbit is set, or either the failbit or badbit is set. |
operator!
| Equivalent to fail(). |
operator bool
| Equivalent to !fail(). |
rdstate()
| Returns the current ios_base::iostate state. |
clear(state)
| Changes the state of the stream to the given one if a valid stream buffer is attached (see later); otherwise sets it to state | badbit. |
setstate(state)
| Calls clear(state | rdstate()). |
Besides these state-related methods, the following additional ones are defined by ios:
Method | Description |
---|---|
fill()
fill(char)
| Returns the current fill character, or changes it while returning the old one. To change it, you can also use the setfill() manipulator. |
copyfmt()
| Copies everything from another ios instance except its state. |
tie()
| Ties any output stream to the this stream, which means the tied output stream is flushed each time an input or output operation is performed on the this stream. |
narrow()
widen()
| Converts a wide character to its narrow equivalent or vice versa in a locale-specific manner. See Chapter 6 for details on locales.
|
The default initialization of std::ios has the following effect:
- Flags are set to skipws | dec.
- Precision is set to 6.
- The field width is set to 0.
- The fill character is set to widen(' ').
- The state is set to goodbit if there is a valid stream buffer attached (see later), or badbit otherwise.
Error Handling
By default, stream operations report errors by setting the state bits (good, bad, fail, and eof) of the stream, but they do not throw exceptions. Exceptions can be enabled, though, with the exceptions() method. It either returns the current exceptions mask or accepts one. This mask is a bitwise combination of std::ios_base::iostate state flags (see Table 5-3). For each state flag in the mask that is set to 1, the stream throws an exception when that state bit is set for the stream.
For example, the following code tries to open a nonexistent file using a file stream (explained in detail later in this chapter). No exceptions are thrown; only the fail bit of the stream is set to 1:
If you want to use exceptions instead, the code can be rewritten as follows:
A possible output could be
ios_base::failbit set: iostream stream error
std::ostream <ostream>
The ostream class supports formatted and unformatted output to
char-based streams
. Formatted output means the format of what is written can be influenced by formatting options, such as the width of a field, the number of decimal digits for floating-point numbers, and so on. Formatted output is generally also influenced by the stream’s locale, as explained in Chapter 6. Unformatted output entails simply writing characters or character buffers as is.
ostream provides a
swap() method
and the following high-level output operations. If no return type is mentioned, the operation returns an ostream&, allowing operations
to be chained:
Operation | Description |
---|---|
operator<<
| Writes formatted data to the stream. |
put(char)
write(const char*, n)
| Writes a single character or n characters unformatted to the stream. |
fpos tellp()
seekp(pos)
seekp(off, dir)
| Returns or changes the current position in the stream. The p is shorthand for put and denotes that these methods are working on an output stream. seekp() accepts either an absolute position (fpos) or an offset (streamoff) and a direction (seekdir: see Table 5-4) in which to start the offset. |
flush()
| Forcefully flushes the buffer to the target. |
Table 5-4.
std::ios_base::seekdir Constants Defined
in <ios>
seekdir | Description |
---|---|
beg
| The beginning of the stream |
end
| The end of the stream |
cur
| The current position in the stream |
<ostream> also defines the following extra I/O manipulators
:
Manipulator | Description |
---|---|
ends
| Writes |