Previous Section: Strings
 
Main Menu for the Essentials of C++
Next Section: Templates

Essentials of C++: Section XIV

Input and Output

Standard 'C' included the scanf and printf functions to handle input and output. While they are still part of C++, they are not as popular as the newer approach found in C++ and are not described here.

In C++ input and output is most often viewed in terms of various kinds of data paths or streams. There are a number of different kinds of streams, each represented by a class. The collection of such classes forms an inheritance structure as shown here:

The classes that are most important for our purposes are:

ios
istream
ostream
ifstream
ofstream
iostream

The first three of these and the last one are declared in the file 'iostream.h'. The other two are declared in 'fstream.h'.
 

A. The Base Class ios: Its Data Members
As the base class for the whole input-output inheritance structure, the ios class provides much of the basic structure and functionality for all input and output. One key aspect is the state of a stream instance. One integer data member for this class, flags, represents the state information for input-output formatting, using the individual bits of the integer field to indicate specific formatting features. To provide easy access to these bits, they are each represented by a constant declared in an enumeration. There are also a set of constants representing logical groupings of these flags where only one of the flags in the group can be set at any one time. These groupings are called bit fields.

enum { skipws Should white space (blanks) be skipped on input
 
// The 'adjustfield' group (ios::adjustfield)
left Display output as left justified.
right
Display output as right justified.
internal Display any sign as left justified and the rest as right justified.
 
// The 'basefield' group (ios::basefield)
dec Use decimal notation for numeric output and assume the same for input.
oct Use octal notation for numeric output and assume the same for input.
hex Use hex notation for numeric output and assume the same for input.
 
showbase Display the base on numeric output.
showpoint Display decimal point for all floating-point (real) output.
uppercase Use uppercase in exponential and hex number output.
showpos Display sign for positive integers.
 
// The 'floatfield' group (ios::floatfield)
scientific Use scientific notation to display floating-point numbers.
fixed Use fixed-point notation to display floating-point numbers.
unitbuf Flush output stream after writing to it.
stdio Flush the stdout and stderr streams after writing to them.
};

A number of these flags or bit fields have defaults:

Flag or Bit Field Default
 
skipws White space is skipped
ios::adjustfield           Right justification
ios::basefield Use decimal notation

Discussion in 'The Story of C++"

The Use of 'left' and 'right' for Field Justification

A second set of flags handles error states. These states represent a greater level of detail than we need to examine here but can be summarized as four states with which there are corresponding member functions as described later. The four states are:

good           The stream has not encountered a problem.
eof The end of file has been reached. This is not really an error but is included here because it represents something encountered by the stream.
fail An input or output operation has failed but processing can continue.
bad A severe error has occurred.

Discussion in "The Story of C++"

Using the 'fail' Flag

There are three other ios data members relevant to the state of a stream:

width On output: the size of the field where data will be printed
On input:   the maximum number of characters (minus 1)to be read in
Default:     0 (Meaning that one character will be read.)
 
fill The character to pad unfilled fields
Default: blank
precision     The precision of floating point output
If either of the ios::floatfield flags is set, this refers to the number of digits to the right of the decimal; otherwise, it refers to the total number of digits to be printed.

Finally, there is an enumerated type for indicating the relationship between the stream and some file. (Input and output devices are considered to be files as far as C++ is concerned.) In declaring a stream we attach the stream to a file and open the