C++ Syntax: Input/Output: << >>

Description

Standard Streams

The standard I/O system is declared in the header file:-
#include <iosteam.h>
I/O sources and sinks are called streams. 3 are defined in the header:-
  1. cin The standard input, normally the keyboard.
  2. cout The standard output, normally the screen.
  3. cerr The error output, normally the screen.
I/O can be achieved just by using the appropriate function defined in the header. To print out the value of some basic type called x followed by a newline ("\n"):-
put(cout,"x = ");
put(cout,x);
put(cout,"\n");
Two functions are being used here, but they are both called put, (i.e. the function is overloaded). It is the compiler's job to work out which to use based on the context, i.e. the type of arguments.

Overloading << and >>

The above is verbose so a more elegant way is provided. The C++ language does not include an I/O system, but one of its core concepts is that it is extendible. Although its operator set cannot be increased, the meanings of operators depend on the context in which they are used. When applied to new objects the meaning can be redefined. So, the left shift operator << has, in the standard I/O library, been overloaded to be the put function when its left hand argument is an input stream. Hence:-
cout <<  "x = ";
is the same as
put(cout,"x = ");
The side effect is to output the right hand variable and the expression produces a value that is an output stream (technically its a reference to an output stream, but it amounts to the same thing). This value can be used again as the left hand size of a <<. So to call the put functions 3 times as before:-
cout << "x = " << x << "\n";
because the << operator is evaluated left to right. It take a little getting used to for a FORTRAN programmer, but after a while you get used to seeing this as a cout object with a stream of values flowing into it.

As you might expect, input simply reverses the sign on the flow, so to read 3 numbers from the input stream and store them in x, y, z:-

cin >> x >> y >> z;

Modifiers

At first sight this all looks very inflexible. What if you want to format the output to print floating point numbers to 3 decimal places? The solution is to introduce special data types into the values being input or output and then to define new functions that overload the shift operators to be called when it comes across such data types. Consider:-
cout << hex  << my_int  << endl;
hex and endl are manipulators, that result in special functions being called when they are processed:- There are more complicated manipulators that take arguments, for example:-
cout << setprecision(4) << my_float;
This sets floating point precision to 4 digits, ready to output my_float. Manipulators that take arguments are a bit more complicated. Basically, the function setprecision creates an object that knows what the user wants. Then the compiler finds an definition of the << operator that can be used with this object, and this definition calls the object to do the user's bidding. You don't need to know any of this, but it is a nice example of how flexible objects are, in this case being created just to pass a message from the user to the output stream. To use manipulators that take arguments you have to include:-
#include <iomanip.h>
A couple of other manipulators of this type are:-

Extending the I/O System

Although the standard streams know only how to perform I/O on the standard data types, the user can extend the operators to apply to his or her own classes. It is also possible to define new streams. ROOT does this in its I/O, defining the << and the >> to stream data to/from its own buffer classes.

See operator precedence

Other Uses for << >>

<< >> are the shift operators. As explained above this is an example of operator reuse.

Usage Notes

None.
Go Back to the The C++ Crib Top Page


If you have any comments about this page please send them to Nick West