Format Control

You can change the width, the justification (right or left), the precision of floating-point values, and the radix, among others. This section explains some of the available output stream formatting options.

This section introduces the term “manipulator.” If you are interested in how manipulators fit into the C++ language, see “Writing Your Own Manipulators without Parameters” on page 381. Otherwise, consider the predefined manipulators to be elements of the iostream syntax expressions used in conjunction with the insertion (and extraction) operators.

Output Width

In this book, many examples show data values separated by spaces. If you need output that is lined up in columns, you must specify the output width.

You can specify a width for each displayed item by placing the setw manipulator in the stream or by calling the width member function. Both the setw manipulator and the width member function take a width parameter.

Example 1

Example 1 prints a column of numbers without specifying an output width:

// exios101.cpp

// Displaying columns of numbers

#include <iostream.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

for( int i = 0; i < 4; i++ )

cout << values[i] << '\n';

}

The output looks like this:

1.23

35.36

653.7

4358.24

Example 2

Example 2 shows how the width member function manages output width. By calling the width function with an argument of 10, the program specifies that the displayed values are to appear right-aligned in a column at least 10 characters wide.

// exios102.cpp

// The width member function

#include <iostream.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

for( int i = 0; i < 4; i++ )

{

cout.width(10);

cout << values[i] << '\n';

}

}

The output from this example looks like this:

1.23

35.36

653.7

4358.24

In this example, leading blanks are added to any value that is less than 10 characters wide. Later, you will learn how to replace the leading blanks with specified padding characters.

Example 3

Sometimes you need different widths for different data elements in the same line. The width member function provides this capability, but the setw manipulator is more convenient, as Example 3 illustrates:

// exios103.cpp

// The width member function

#include <iostream.h>

#include <iomanip.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };

for( int i = 0; i < 4; i++ )

cout << setw( 6 ) << names[i]

<< setw( 10 ) << values[i] << endl;

}

Note that the width member function is declared in IOSTREAM.H, but if you use the setw manipulator (or any other manipulator with parameters), you must include both IOSTREAM.H and IOMANIP.H. Also note that the newline character ('\n') has been replaced by the endl manipulator.

In the output from this example, the strings are printed with a width of six and the integers with a width of ten.

Zoot 1.23

Jimmy 35.36

Al 653.7

Stan 4358.24

Neither setw nor width truncate values. If the formatted output exceeds the current width, the entire value prints, subject to the stream's current precision setting. You should be aware of this behavior when you design formatted displays that use setw or width.

Note:

Both setw and width affect the following field only. The field width reverts to its default behavior (the necessary width) after one field has been printed. The other stream format options remain in effect until changed.

Padding

You can use the fill member function to set the value of the padding character for fields that have a specified width. The default padding character is a blank.

Example 4

In Example 4 a column of numbers is padded with asterisks:

// exios104.cpp

// The fill member function

#include <iostream.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

for( int i = 0; i < 4; i++ )

{

cout.width( 10 );

cout.fill( '*' );

cout << values[i] << endl;

}

}

The values print as follows:

******1.23

*****35.36

*****653.7

***4358.24

Alignment

So far, all output from the example programs has printed flush right within the width field. Output streams default to right-aligned text.

Example 5

Suppose that you want the names in Example 3 to be left-aligned and the number to remain right-aligned. You can use the setiosflags manipulator to specify that the output is to be left- or right-aligned. Example 5 shows how to left-align the names:

// exios105.cpp

// The setiosflags and resetiosflags manipulators

#include <iostream.h>

#include <iomanip.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

char *names[] = { "Zoot", "Jimmy", "Al", "Stan "};

for ( int i = 0; i < 4; i++ )

cout << setiosflags( ios::left )

<< setw( 6 ) << names[i]

<< resetiosflags( ios::left )

<< setw( 10 ) << values[i] << endl;

}

The output looks like this:

Zoot 1.23

Jimmy 35.36

Al 653.7

Stan 4358.24

The example sets the left-align flag by using the setiosflags manipulator with an argument of ios::left. This argument is an enumerator that is defined in the ios class, so its reference must include the ios:: prefix. The resetiosflags manipulator turns off the left-align flag to return to the default right-align mode.

Note:

Unlike width and setw, the effect of setiosflags and resetiosflags is permanent. If you turn on left-alignment, for example, it stays on until you turn it off.

Precision

Suppose you want the floating-point numbers in Example 5 to display with only one significant digit. The setprecision manipulator tells the object to use a specified number of digits of precision.

Example 6

Example 6 limits the displayed precision to one significant digit.

// exios106.cpp

// The setprecision manipulator

#include <iostream.h>

#include <iomanip.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };

for ( int i = 0; i < 4; i++ )

cout << setiosflags( ios::left )

<< setw( 6 )

<< names[i]

<< resetiosflags( ios::left )

<< setw( 10 )

<< setprecision( 1 )

<< values[i]

<< endl;

}

The program prints this list:

Zoot 1

Jimmy 4e+001

Al 7e+002

Stan 4e+003

Example 7

You might want to eliminate the scientific notation in Example 6. Two flags, ios::fixed and ios::scientific, control how a floating-point number prints. You can set and clear these flags with the setiosflags and resetiosflags manipulators:

// exios107.cpp

// The fixed flag

#include <iostream.h>

#include <iomanip.h>

void main()

{

double values[] = { 1.23, 35.36, 653.7, 4358.24 };

char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };

cout << setiosflags( ios::fixed );

for ( int i = 0; i < 4; i++ )

cout << setiosflags( ios::left )

<< setw( 6 )

<< names[i]

<< resetiosflags( ios::left )

<< setw( 10 )

<< setprecision( 1 )

<< values[i]

<< endl;

}

With fixed notation, the program prints with one digit after the decimal point.

Zoot 1.2

Jimmy 35.4

Al 653.7

Stan 4358.2

If, in Example 7, the ios::fixed flag is changed to ios::scientific, the program's behavior changes, and it prints this:

Zoot 1.2e+000

Jimmy 3.5e+001

Al 6.5e+002

Stan 4.4e+003

Again, the program prints one digit after the decimal point. Example 7 shows that if either the ios::fixed flag or the ios::scientific flag is set, then the precision value determines the number of digits after the decimal point. If neither flag is set, then the precision value determines the total number of significant digits.

Note:

The default value of precision is six. This means that a number such as 3466.9768 prints as 3466.98 unless ios::fixed or ios::scientific is set, in which case it prints as 3466.976800 or 3.466977e+003, respectively.

Radix

The dec, oct, and hex manipulators set the default radix for both input and output. If you insert the hex manipulator into the output stream, for example, the object correctly translates the internal data representation of integers into a hexadecimal (base 16) output format. The default radix is dec (decimal).

On insertion, the hex manipulator causes integers and long integers to be converted to hexadecimal format. The numbers are displayed with digits a through f in lower case if the flag ios::uppercase is clear (the default); otherwise they are displayed in upper case. Thus, for example, the decimal integer 28 is displayed as 1c. The ios::uppercase flag is described in Part 3 of the Class Libraries Reference (iostream section) under the flags member function of class ios.