Поделиться через


Using Insertion Operators and Controlling Format

This topic shows how to control format and how to create insertion operators for your own classes. The insertion (<<) operator, which is preprogrammed for all standard C++ data types, sends bytes to an output stream object. Insertion operators work with predefined "manipulators," which are elements that change the default format of integer arguments.

You can control the format with the following options:

  • Output Width

  • Alignment

  • Precision

  • Radix

Output Width

To align output, you specify the output width for each item by placing the setw manipulator in the stream or by calling the width member function. This example right-aligns the values in a column at least 10 characters wide:

// output_width.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

int 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';
   }
}

Output

      1.23
     35.36
     653.7
   4358.24

Leading blanks are added to any value fewer than 10 characters wide.

To pad a field, use the fill member function, which sets the value of the padding character for fields that have a specified width. The default is a blank. To pad the column of numbers with asterisks, modify the previous for loop as follows:

for( int i = 0; i < 4; i++ )
{
   cout.width( 10 );
   cout.fill( '*' );
   cout << values[i] << endl;
}

The endl manipulator replaces the newline character ('\n'). The output looks like this:

******1.23
*****35.36
*****653.7
***4358.24

To specify widths for data elements in the same line, use the setw manipulator:

// setw.cpp
// compile with: /EHsc
#include <iostream>
#include <iomanip>
using namespace std;

int 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;
}

Output

The width member function is declared in <iostream>. If you use setw or any other manipulator with arguments, you must include <iomanip>. In the output, strings are printed in a field of width 6 and integers in a field of width 10:

  Zoot      1.23
 Jimmy     35.36
    Al     653.7
  Stan   4358.24

Neither setw nor width truncates values. If formatted output exceeds the width, the entire value prints, subject to the stream's precision setting. Both setw and width affect the following field only. Field width reverts to its default behavior (the necessary width) after one field has been printed. However, the other stream format options remain in effect until changed.

Alignment

Output streams default to right-aligned text. To left-align the names in the previous example and right-align the numbers, replace the for loop as follows:

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 left-align flag is set by using the setiosflags manipulator with the left enumerator. This enumerator is defined in the ios class, so its reference must include the ios:: prefix. The resetiosflags manipulator turns off the left-align flag. Unlike width and setw, the effect of setiosflags and resetiosflags is permanent.

Precision

The default value for floating-point precision is six. For example, the number 3466.9768 prints as 3466.98. To change the way this value prints, use the setprecision manipulator. The manipulator has two flags: fixed and scientific. If fixed is set, the number prints as 3466.976800. If scientific is set, it prints as 3.4669773+003.

To display the floating-point numbers shown in Alignment with one significant digit, replace the for loop as follows:

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

To eliminate scientific notation, insert this statement before the for loop:

cout << setiosflags( ios::fixed );

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 you change the ios::fixed flag to ios::scientific, the program 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. If either ios::fixed or ios::scientific is set, the precision value determines the number of digits after the decimal point. If neither flag is set, the precision value determines the total number of significant digits. The resetiosflags manipulator clears these flags.

Radix

The dec, oct, and hex manipulators set the default radix for input and output. For example, if you insert the hex manipulator into the output stream, the object correctly translates the internal data representation of integers into a hexadecimal output format. The numbers are displayed with digits a through f in lower case if the uppercase flag is clear (the default); otherwise, they are displayed in upper case. The default radix is dec (decimal).

See Also

Reference

Output Streams