| |
Main Menu | Next Section |
III. Basic Output Using Instances of the Class ostream
A. The '<<' Operator
There is little new to say about '<<' by itself. We can,
however, extend its power through the use of various special characters,
manipulators, and member functions. You have already learned the
use of the '\n' special character. Another useful one is '\t'
that allows you to tab over in your output. For example, if you
wanted to create nice column headings you might write the following
code:
This will cause the output after each '\t' to begin at the next
tab stop. Check your manual to see how tab stops are set in the
environment your program will run in.
Sometimes we want the output to include characters that have special
meaning in C++ output. For example, one might want to output double
quotes ("). Since this symbol means the end of a string in
C++, one cannot use it without special care in an output expression.
To tell C++ that such a symbol is not to be understood in its
C++ sense, one puts a backslash character in front of the symbol.
Thus one could output 'He said, "Hello"' (with the quotes
as part of the output) this way:
The quote symbols preceded by back slashes become part of the
output. (The back slashes are not part of the output.)
There is a third, "kinda fun" special character you
might want to play with. This is the '\a' character that causes
the computer to "ring its bell". You might want to use
this if a user types in an incorrect value so they will look up
and read the error message you also display. (The system just
'dinged' when one of the authors tried to arrow past the last
word in this file.)
B. Various Manipulators to Improve the Quality of Your Output
Suppose you want to output some set of information about the people in a database. For example, suppose you want to output the name, telephone number, age, and height (in feet) of the individuals in the database. One nice way to do this would be to create a typical table with labeled columns for each property and the property values themselves in the appropriate column. One might consider using tabs to line up the columns, but it turns out that tabs are not flexible enough and are somewhat system dependent. The 'setw' manipulator works better. Consider the following code fragment. (Remember that, to use 'setw', one must include the header file "iomanip.h"):
cout << endl; // to make sure a new line is started
cout << setw(30) << "Name" << setw(16) << "Phone Number"
<< setw(6) << "Age" << setw(10) << "Height" << endl;
cout << setw(30) << "Curtis" << setw(16) << "505-454-3302"
<< setw(6) << 6 << setw(10) << 5.75 << endl;
cout << setw(30) << "Fred Smith" << setw(16) << "505-454-3302"
<< setw(6) << 102 << setw(10) << 5.128 << endl;
In a real program, the code would not include string and numeric constants for property values, as this code does, but would use variables instead. However, the use of constants here makes it easier to study the results.
As coded, the output would be:
Name Phone Number Age Height
Curtis 505-454-3302 6 5.75
Fred Smith 505-454-3302 102 5.128
You may have noticed one problem - we humans like our numbers
right justified but our strings left justified. In other words,
we would prefer that the names all start in the same column. As
written, the code will not allow this because, by default, the
output is right justified within each block. In other words, the
output is, by default, placed at the right end of the blocks.
We talked about inheritance earlier in this chapter. Many of the
properties of streams are declared in the base class, 'ios', of the stream
inheritance structure. Whether output is
left or right justified, is indicated by which of two one bit flags
(ios::left and ios::right) is set. (Note that only one can be
set at a time.)
To set these flags, you use the 'setiosflags' manipulator, which is declared in the header file iomanip.h along with 'setw'. Thus, to left justify everything, we could preface the lines above with the following code:
Of course, since everything is left justified now, the output
would look as follows:
Name Phone Number Age Height Curtis 505-454-3302 6 5.75 Fred Smith 505-454-3302 102 5.128
cout << endl; // to make sure a new line is started
cout << setw(30) << setiosflags(ios::left) << "Name" << setiosflags(ios::right)
<< setw(16) << "Phone Number"
<< setw(6) << "Age" << setw(10) << "Height" << endl;
cout << setw(30) << setiosflags(ios::left) << "Curtis" << setiosflags(ios::right)
<< setw(16) << "505-454-3302"
<< setw(6) << 6 << setw(10) << 5.75 << endl;
cout << setw(30) << setiosflags(ios::left) << "Fred Smith" << setiosflags(ios::right)
<< setw(16) << "505-454-3302"
<< setw(6) << 102 << setw(10) << 5.128 << endl;
Name Phone Number Age Height Curtis 505-454-3302 6 5.75 Fred Smith 505-454-3302 102 5.128
The '::' operator indicates that 'ChangeAge' belongs to the class
'Person'. It would be possible to have a different function with
the same name, 'ChangeAge', that belonged to a different class
(perhaps an animal or building class). Likewise, the designation
'ios::left' indicates that 'left' in this case belongs to the
class 'ios'. We can have a variable 'left' that belongs to a different
class or to no class at all. To differentiate between the various
'left' variables, we use the '::' symbol. Note that we do not
use this inside a class's member function definitions, because
the default assumption is that we are referring to the data member
names of an instance of that class.
There are any number of other manipulators and member functions
that can be used to shape output. We will look at just one more.
The 'Height' field in the output, as coded above, can have any
number of digits to the right of the decimal point. Suppose, for
whatever reason, that we only wanted two places to the right of
the decimal point. We can accomplish this using two more properties
of a stream. The first property is another 'flag' to indicate
whether fixed or scientific notation is used for floating point
numbers. (Scientific notation expresses floating point values
using exponents while fixed notation is what we are most familiar
with.)
The second property handles the total number of digits to be printed if neither ios::fixed or ios::scientific is chosen, or, if one of these is chosen, the number of digits to the right of the decimal point. Since we want two decimal points to the right of the decimal point
and we want fixed notation, we add the lines:
Name Phone Number Age Height Curtis 505-454-3302 6 5.75 Fred Smith 505-454-3302 102 5.13
Topics Covered in the "Essentials of C++"
| |
Main Menu | Next Section |