The iostream
library provides many templates for handling common I/O operations. For example, class template basic_istream supports stream-input operations, class template basic_ostream supports stream-output operations, and class template basic_iostream supports both stream-input and stream-output operations. Each template has a predefined template specialization that enables char
I/O. In addition, the iostream
library provides a set of typedef
s that provide aliases for these template specializations. The typedef specifier declares synonyms (aliases) for data types. You’ll sometimes use typedef
to create shorter or more readable type names. For example, the statement
typedef Card *CardPtr;
defines an additional type name, CardPtr
, as a synonym for type Card *
. Creating a name using typedef
does not create a data type; it creates only a new type name. Section 20.3 discusses typedef
in detail. The typedef istream
represents a basic_istream<char>
that enables char
input. Similarly, the typedef ostream
represents a basic_ostream<char>
that enables char
output. Also, the typedef iostream
represents a basic_iostream<char>
that enables both char
input and output. We use these typedef
s throughout this chapter.
Templates basic_istream
and basic_ostream
both derive through single inheritance from base template basic_ios.1 Template basic_iostream
derives through multiple inheritance2 from templates basic_istream
and basic_ostream
. The UML class diagram of Fig. 13.1 summarizes these inheritance relationships.
1. This chapter discusses templates only in the context of the template specializations for char
I/O.
2. Multiple inheritance is discussed in Chapter 21, Other Topics.
Operator overloading provides a convenient notation for performing input/output. The left-shift operator (<<) is overloaded to designate stream output and is referred to as the stream insertion operator. The right-shift operator (>>) is overloaded to designate stream input and is referred to as the stream extraction operator. These operators are used with the standard stream objects cin
, cout
, cerr
and clog
and, commonly, with stream objects you create in your own code.
Predefined object cin
is an istream
instance and is said to be “connected to” (or attached to) the standard input device, which usually is the keyboard. The stream extraction operator (>>
) as used in the following statement causes a value for integer variable grade
(assuming that grade
has been declared as an int
variable) to be input from cin
to memory:
cin >> grade; // data "flows" in the direction of the arrows
The compiler determines the data type of grade
and selects the appropriate overloaded stream extraction operator. Assuming that grade
has been declared properly, the stream extraction operator does not require additional type information (as is the case, for example, in C-style I/O). The >>
operator is overloaded to input data items of fundamental types, strings and pointer values.
The predefined object cout
is an ostream
instance and is said to be “connected to” the standard output device, which usually is the display screen. The stream insertion operator (<<
), as used in the following statement, causes the value of variable grade
to be output from memory to the standard output device:
cout << grade; // data "flows" in the direction of the arrows
The compiler determines the data type of grade
(assuming grade
has been declared properly) and selects the appropriate stream insertion operator. The <<
operator is overloaded to output data items of fundamental types, strings and pointer values.
The predefined object cerr
is an ostream
instance and is said to be “connected to” the standard error device, normally the screen. Outputs to object cerr
are unbuffered, implying that each stream insertion to cerr
causes its output to appear immediately—this is appropriate for notifying a user promptly about errors.
The predefined object clog
is an instance of the ostream
class and is said to be “connected to” the standard error device. Outputs to clog
are buffered. This means that each insertion to clog
could cause its output to be held in a buffer (that is, an area in memory) until the buffer is filled or until the buffer is flushed. Buffering is an I/O performance-enhancement technique discussed in operating-systems courses.
C++ file processing uses class templates basic_ifstream (for file input), basic_ofstream (for file output) and basic_fstream (for file input and output). As with the standard streams, C++ provides typedef
s for working with these class templates. For example, the typedef ifstream
represents a basic_ifstream<char>
that enables char
input from a file. Similarly, typedef ofstream
represents a basic_ofstream<char>
that enables char
output to a file. Also, typedef fstream
represents a basic_fstream<char>
that enables char
input from, and output to, a file. Template basic_ifstream
inherits from basic_istream
, basic_ofstream
inherits from basic_ostream
and basic_fstream
inherits from basic_iostream
. The UML class diagram of Fig. 13.2 summarizes the various inheritance relationships of the I/O-related classes. The full stream-I/O class hierarchy provides most of the capabilities that you need. Consult the class-library reference for your C++ system for additional file-processing information.