C++ Stream I/O
Streams:
-
Streams are sequences of bytes.
-
Input streams: Flow from a device or source (keyboard, network, file)
into memory
-
Output streams: Flow from memory into a device or destination (monitor,
printer, file)
-
Streams can read/write formatted and unformatted data. (Unformatted
= raw bytes. Usually binary info).
-
The <iostream> header contains declarations of 4 pre-built
stream objects
-
cin - Standard input stream
-
cout - Standard output stream
-
cerr - Standard error stream (unbuffered)
-
clog - Standard error stream (buffered)
-
<fstream> library - contains services for file I/O (discussed
previously)
-
<iomanip> library - contains functions and stream manipulators
for controlling formatting of I/O.
Stream Output
-
Many built-in insertion operator (<<) functions
-
put() member function - outputs a single character
-
can be cascaded, like the << operator
-
Ex: cout.put('B').put('o').put('b');
-
write() member function - for unformatted output (raw bytes)
from a buffer
-
The endl stream manipulator
-
outputs a newline and flushes the output buffer
-
cout << endl; is equivalent to cout
<< '\n' << flush;
Stream Input
-
Many built-in extraction operator (>>) functions
-
default behavior of all built-in >> operators is to ignore leading white
space characters
-
returns stream object for cascading (or returns 0 -- i.e. false
-- when the end-of-file is encountered on the stream)
-
get() member functions
-
version with no parameters extracts next character from stream (even white
space) and returns it
-
version with one by-reference char parameter extracts next character from
strem (even white space) and loads it into parameter, then returns reference
to the stream object (or 0 for end-of-file).
-
get() and getline() - for reading C-style
strings
-
three parameters, last has default value of newline. Previously discussed.
-
read() member function - for unformatted input (raw bytes)
into a buffer
-
peek() member function - returns the next character from
stream (like get()), but does not extract it.
-
ignore() member function - skips either a designated number
of characters, or skips up to a specified delimiter. Examples:
-
cin.ignore(); // means skip
the next 1 character of input
-
cin.ignore(30); // means skip the next 30 characters
of input
-
cin.ignore(100,'\n'); // means skip to the next newline,
up to 100 characters maximum (i.e. skip no more than 100).
-
putback() member function - puts a character back into
the input stream
-
Input stream objects also contain state bits, which help with formatting
and error checking. For instance, if an unexpected type of data is
entered, the failbit is set, which can be tested by the program.
Additional code examples illustrating:
- ignore
- putback
- peek
Stream State Bits
There are several bit flags in every stream object
-
eofbit - set to 1 to indicate end of file encountered on an input
stream
-
failbit - set when a format error occurs on the stream (like a non-digit
occurring on an integer input)
-
badbit - set when an error occurs that results in loss of data (usually
a more serious, non-recoverable failure)
-
goodbit - set when eofbit, failbit, and badbit are not set.
There are member functions that are used to return the values of the bit
flags. The corresponding functions return true when the bit
is set, and false when the bit is not set (i.e. is 0).
-
eof() - returns true when eofbit is set
-
fail() - returns true when failbit is set
-
bad() - returns true when badbit is set
-
good() - returns true when goodbit is set
-
rdstate() - returns the error state of the stream (the
combination of bits)
-
clear() - used to restore a stream's state to "good" (when
called with no parameters)
Here is an example from Deitel that illustrates the return values from
these functions: fig12_22.cpp
Here is a more practical example that illustrates how to check the fail
bit to recover from an invalid type being entered on an input stream:
I/O Formatting with <iomanip>
Stream manipulators are various symbols or functions in the
<iomanip>
library that are used in conjunction with the insertion operator for output
streams (or the extraction operator for input streams). Most of them
are used primarily for formatting output. An example of a stream
manipulator is the hex manipulator, which causes integers to be
printed out in hexadecimal format. Sample usage would look like this:
int x = 12345;
cout << hex << x;
Some stream manipulators are equivalent to corresponding member functions
(which are called through the usual dot-operator). Most stream manipulators
set formatting for the entire stream -- meaning that the set format will
apply until another manipulator changes it. For example, the hex
manipulator will cause all successive integer outputs to be in hex format
until the format is reset to something different.
Some common stream manipulators
-
hex, oct, dec, and setbase() stream manipulators
-
control the base that integers are printed in
-
hex = hexadecimal format. oct = octal format. dec = decimal
format
-
setbase takes one parameter - either 10, 8, or 16 (for decimal, octal,
or hex, respectively).
-
Ex: cout << hex;
-
Ex: cout << setbase(8);
-
setprecision() stream manipulator
-
can also use precision() member function
-
precision() called with no parameters will return the current
precision setting
-
Examples:
-
cout.precision(2); // sets float precision to 2 decimal places
-
cout << setprecision(3); // sets to 3 decimal places
-
setw() stream manipulator (and corresponding member function width()).
-
This manipulator (or function call) only affects the next output
item.
-
Sets the field width of the next output item (or input item, when used
with an istream object).
-
if the field size is larger than the output, fill characters will
be inserted as padding (default is the space).
-
Examples:
-
cout << setw(10) << x; // output contents of variable x
in field width of 10
-
cout.width(20); cout << y; // output y in field width
of 20
-
setfill() stream manipulator (and corresponding member function
fill())
-
sets the fill character used in justified fields
-
Examples
-
cout << setfill('*');
-
cout.fill('.');
-
left, right, and internal
-
stream manipulators that set justification within a field.
-
internal means that a number's sign is left justified, and the
value (magnitude) is right-justified
-
skipws - skips whitespace characters on an input stream
-
this is reset with noskipws
-
showpoint - specifies that floating point numbers should always
be output with the decimal point
-
this is reset with noshowpoint
-
showpos - specifies that the + sign should specifically appear
before positive numbers
-
scientific and fixed
-
set format of floating point numbers -- either scientific notation, or
fixed decimal point notation
-
showbase - specifies that the base indicator is present in the
output of an integer
-
decimal format has no prefix
-
octal numbers are prefixed with a leading 0
-
hex numbers are prefixed with 0x
-
reset with noshowbase
-
uppercase - specifies that uppercase letters are used in hex outputs
(A-F) and scientific notation (E)
Code Examples (from Deitel):
Important Note
Some of these features of <iomanip>, especially some of the
stream manipulators, constitute a newer style of formatting and only work
on newer compilers. In older style libraries, some of the format flags
were set via the use of special member functions like
setf, unsetf, and
flags -- or with parameterized stream manipulators like
setiosflags() and resetiosflags.
Example: The newer vs. older style for a few format flags.
cout << left; // newer style
cout << setiosflags(ios::left); // older style
cout << fixed; // newer style
cout << setiosflags(ios::fixed); //older style
The 3rd edition of Deitel contains examples that are in the older
style. You can find these here.
If the newer style stream manipulators don't work with a certain
compiler, then you will probably have to use the older ones
Some affected manipulators:
left
right
internal
showbase
skipws
showpoint
uppercase
showpos
scientific
fixed