C++

Chapter – 4

Input and Output with Streams

This chapter describes the use of streams for input and output, focusing on formatting techniques.

 ■ STREAMS

Stream classes for input and output :

The four standard streams

  • cin     Object of class istream to control standard input
  • cout    Object of class ostream to control standard output
  • cerr    Object of class ostream to control unbuffered error output
  • clog    Object of class ostream to control buffered error output

□   I/O Stream Classes

During the development of C++ a new class-based input/output system was imple- mented. This gave rise to the I/O stream classes, which are now available in a library of their own, the so-called iostream library.

The diagram on the opposite page shows how a so-called class hierarchy develops due to inheritance. The class ios is the base class of all other stream classes. It contains the attributes and abilities common to all streams. Effectively, the ios class

  • Manages the connection to the physical data stream that writes your program’s data to a file or outputs the data on screen
  • Contains the basic functions needed for formatting data. A number of flags that determine how character input is interpreted have been defined for this purpose.

The istream and ostream classes derived from ios form a user-friendly interface for stream manipulation. The istream class is used for reading streams and the ostream class is used for writing to streams. The operator >> is defined in istream and << is defined in ostream, for example.

The iostream class is derived by multiple inheritance from istream and ostream and thus offers the functionality of both classes.

Further stream classes, a file management class, for example, are derived from the classes mentioned above. This allows the developer to use the techniques described for file manipulation. These classes, which also contain methods for opening and closing files, will be discussed in a later chapter.

□   Standard Streams

The streams cin and cout, which were mentioned earlier, are instances of the istream or ostream classes. When a program is launched these objects are automati- cally created to read standard input or write to standard output.

Standard input is normally the keyboard and standard output the screen. However, standard input and output can be redirected to files. In this case, data is not read from the keyboard but from a file, or data is not displayed on screen but written to a file.

The other two standard streams cerr and clog are used to display messages when errors occur. Error messages are displayed on screen even if standard output has been redirected to a file.

 ■ FORMATTING AND MANIPULATORS

Example: Calling a manipulator

HINTS :
The operators >> and << format the input and/or output according to how the flags in the base class
ios are set
■ The manipulator showpos is a function that calls the method cout.setf(ios::showpos);, 
ios::showpos being the flag showpos belonging to the ios class
■ Using manipulators is easier than directly accessing flags. For this reason, manipulators are described in the following section, whereas the methods setf() and unsetf() are used only under exceptional circumstances.
■ Old compilers only supply some of the manipulators. In this case, you have to use the methods setf()
and unsetf().
□   Formatting

When reading keyboard input, a valid input format must be used to determine how input is to be interpreted. Similarly, screen output adheres to set of rules governing how, for example, floating-point numbers are displayed.

The stream classes istream and ostream offer various options for performing these tasks. For example, you can display a table of numeric values in a simple way.

In previous chapters we have looked at the cin and cout streams in statements such as:
cout << "Please enter a number: ";
cin >> x;

The following sections systematically describe the abilities of the stream classes. This includes:

  • The >> and << operators for formatted input and output. These operators are defined for expressions with fundamental types—that is, for characters, boolean values, numbers and strings.
  • Manipulators, which can be inserted into the input or output stream. Manipula- tors can be used to generate formats for subsequent input/output. One manipula- tor that you are already familiar with is endl, which generates a line feed at the end of a line.
  • Other methods for determining or modifying the state of a stream and unformat- ted input and output.
□   Flags and Manipulators

Formatting flags defined in the parent class ios determine how characters are input or output. In general, flags are represented by individual bits within a special integral vari- able. For example, depending on whether a bit is set or not, a positive number can be output with or without a plus sign.

Each flag has a default setting. For example, integral numbers are output as decimals by default, and positive numbers are output without a plus sign.

It is possible to modify individual formatting flags. The methods setf() and unsetf() can be used for this purpose. However, the same effect can be achieved sim- ply by using so-called manipulators, which are defined for all important flags. Manipula- tors are functions that can be inserted into the input or output stream and thus be called.

■ FORMATTED OUTPUT OF INTEGERS

Manipulators formatting integers

Sample program

□   Formatting Options

The << operator can output values of type short, int, long or a corresponding unsigned type. The following formatting options are available:

  • Define the numeric system in which to display the number: decimal, octal, or hexadecimal
  • Use capitals instead of small letters for hexadecimals
  • Display a sign for positive numbers.

In addition, the field width can be defined for the above types. The field width can also be defined for characters, strings, and floating-point numbers, and will be discussed in the following sections.

□   Numeric System

Integral numbers are displayed as decimals by default. The manipulators oct, hex, and dec can be used for switching from and to decimal display mode.

Example: cout << hex << 11;            // Output: b

Hexadecimals are displayed in small letters by default, that is, using a, b, …, f. The manipulator uppercase allows you to use capitals.

Example: cout << hex << uppercase << 11; //Output: B

The manipulator nouppercase returns the output format to small letters.

□   Negative Numbers

When negative numbers are output as decimals, the output will always include a sign. You can use the showpos manipulator to output signed positive numbers.

Example: cout << dec << showpos << 11; //Output: +11

You can use noshowpos to revert to the original display mode.

When octal or hexadecimal numbers are output, the bits of the number to be output are always interpreted as unsigned! In other words, the output shows the bit pattern of a number in octal or hexadecimal format.

Example: cout << dec << -1 << "   " << hex << -1;

This statement causes the following output on a 32-bit system:

-1   ffffffff

 ■ FORMATTED OUTPUT OF FLOATING-POINT NUMBERS

Manipulators formatting floating-point numbers

Methods for precision

NOTE:
The key word const within the prototype of precision() signifies that the method performs only read operations.

Sample program

□   Standard Settings

Floating-points are displayed to six digits by default. Decimals are separated from the integral part of the number by a decimal point. Trailing zeroes behind the decimal point are not printed. If there are no digits after the decimal point, the decimal point is not printed (by default).

Examples:

cout << 1.0;	  // Output: 1 
cout << 1.234;	  // Output: 1.234
cout << 1.234567; // Output: 1.23457

The last statement shows that the seventh digit is not simply truncated but rounded. Very large and very small numbers are displayed in exponential notation.

Example: cout << 1234567.8; // Output: 1.23457e+06

□   Formatting

The standard settings can be modified in several ways. You can

  • Change the precision, i.e. the number of digits to be output
  • Force output of the decimal point and trailing zeroes
  • Stipulate the display mode (fixed point or exponential).

Both the manipulator setprecision()and the method precision() can be used to redefine precision to be used.

Example:

cout << setprecision(3); // Precision: 3
// or: cout.precision(3);
cout << 12.34;	        // Output: 12.3

Note that the header file iomanip must be included when using the manipulator set- precision(). This also applies to all standard manipulators called with at least one argument.

The manipulator showpoint outputs the decimal point and trailing zeroes. The number of digits being output (e.g. 6) equals the current precision.

Example: cout << showpoint << 1.0; // Output: 1.00000

However, fixed point output with a predetermined number of decimal places is often more useful. In this case, you can use the fixed manipulator with the precision defining the number of decimal places. The default value of 6 is assumed in the following example.

Example: cout << fixed << 66.0;   // Output: 66.000000

In contrast, you can use the scientific manipulator to specify that floating-point numbers are output as exponential expressions.

 ■ OUTPUT IN FIELDS

Element functions for output in fields

Manipulators for output in fields

The manipulators setw() and setfill() are declared in the header file iomanip.

Examples

#include <iostream>	// Obligatory
#include <iomanip>	// declarations 
using namespace std;

1st Example: cout << '|' << setw(6) << 'X' << '|'; 
Output:	    |	X|	// Field width 6 
2nd Example: cout << fixed << setprecision(2)
                  << setw(10) << 123.4 << endl
                  << "1234567890" << endl;
Output:	  123.40	// Field width 10
        1234567890

The << operator can be used to generate formatted output in fields. You can

  • Specify the field width
  • Set the alignment of the output to right- or left-justified
  • Specify a fill-character with which to fill the field.

□   Field Width

The field width is the number of characters that can be written to a field. If the output string is larger than the field width, the output is not truncated but the field is extended. The output will always contain at least the number of digits specified as the field width.

You can either use the width() method or the setw() manipulator to define field width.

Example: cout.width(6);    // or: cout << setw(6);

One special attribute of the field width is the fact that this value is non-permanent: the field width specified applies to the next output only, as is illustrated by the examples on the opposite page. The first example outputs the character ‘X’ to a field with width of 6, but does not output the ‘|’ character.

The default field width is 0. You can also use the width() method to get the current field width. To do so, call width() without any other arguments.

Example: int fieldwidth = cout.width();

□   Fill Characters and Alignment

If a field is larger than the string you need to output, blanks are used by default to fill the field. You can either use the fill() method or the setfill() manipulator to specify another fill character.

Example: cout << setfill('*') << setw(5) << 12;

// Output: ***12

The fill character applies until another character is defined.

As the previous example shows, output to fields is normally right-aligned. The other options available are left-aligned and internal, which can be set by using the manipula- tors left and internal. The manipulator internal left-justifies the sign and right- justifies the number within a field.

Example:

cout.width(6); cout.fill('0');
cout << internal << -123; // Output: -00123

 ■ OUTPUT OF CHARACTERS, STRINGS, AND BOOLEAN VALUES         

Sample program

□   Outputting Characters and Character Codes

The >> operator interprets a number of type char as the character code and outputs the corresponding character:

Example:

char ch = '0';
cout << ch << ' ' << 'A';
// Outputs three characters: 0 A

It is also possible to output the character code for a character. In this case the character code is stored in an int variable and the variable is then output.

Example:

int code = '0';
cout << code;	// Output: 48

The ‘0’ character is represented by ASCII Code 48. The program on the opposite page contains further examples.

□   Outputting Strings

You can use the >> operator both to output string literals, such as “Hello”, and string variables, as was illustrated in previous examples. As in the case of other types, strings can be positioned within output fields.

Example:

string s("spring flowers ");
cout << left	         // Left-aligned
     << setfill('?')	 // Fill character ?
     << setw(20) << s ;  // Field width 20

This example outputs the string “spring flowers??????”. The manipulator

right can be used to right-justify the output within the field.

□   Outputting Boolean Values

By default the << operator outputs boolean values as integers, with the value 0 represent- ing false and 1 true. If you need to output the strings true or false instead, the flag ios::boolalpha must be set. To do so, use either the setf() method or the manipulator boolalpha.

Example:

bool ok = true;
cout << ok << endl	// 1
     << boolalpha << ok << endl; // true

You can revert this setting using the noboolalpha manipulator.

 ■ FORMATTED INPUT

Sample program

// Inputs an article label and a price

#include <iostream>	// Declarations of cin, cout,... 
#include <iomanip>	// Manipulator setw()
#include <string> 
using namespace std;

int main()
{
    string label; double price;
    cout << "\nPlease enter an article label: ";
     // Input the label (15 characters maximum): 
     cin >> setw(16);	// or: cin.width(16); 
     cin >> label;
     cin.sync();	// Clears the buffer and resets 
     cin.clear();	// any error flags that may be set
     cout << "\nEnter the price of the article: "; 
     cin >> price;	// Input the price

    // Controlling output:
    cout << fixed << setprecision(2)  
         << "\nArticle:"
         << "\n Label: " << label
         << "\n Price: " << price << endl;
    // ... The program to be continued 
    return 0;
}
NOTE:
The input buffer is cleared and error flags are reset by calling the sync() and clear() methods. This ensures that the program will wait for new input for the price, even if more than 15 characters have been entered for the label.

The >> operator, which belongs to the istream class, takes the current number base and field width flags into account when reading input:

  • the number base specifies whether an integer will be read as a decimal, octal, or hexadecimal
  • the field width specifies the maximum number of characters to be read for a string.

When reading from standard input, cin is buffered by lines. Keyboard input is thus not read until confirmed by pressing the <Return> key. This allows the user to press the backspace key and correct any input errors, provided the return key has not been pressed. Input is displayed on screen by default.

□   Input Fields

The >> operator will normally read the next input field, convert the input by reference to the type of the supplied variable, and write the result to the variable. Any white space characters (such as blanks, tabs, and new lines) are ignored by default.

Example: char ch;
cin >> ch; // Enter a character

When the following keys are pressed

<return> <tab> <blank> <X> <return>

An input field is terminated by the first white space character or by the first character that cannot be processed.

Example:

int i;
cin >> i;

Typing 123FF<Return> stores the decimal value 123 in the variable i. However, the characters that follow, FF and the newline character, remain in the input buffer and will be read first during the next read operation.

When reading strings, only one word is read since the first white space character will begin a new input field.

Example:

string city;
cin >> city; // To read just one word!

If Lao Kai is input, only Lao will be written to the city string. The number of charac- ters to be read can also be limited by specifying the field width. For a given field width of n, a maximum of n–1 characters will be read, as one byte is required for the null charac- ter. Any initial white space will be ignored. The program on the opposite page illustrates this point and also shows how to clear the input buffer.

 ■ FORMATTED INPUT OF NUMBERS

Sample program

□   Inputting Integers

You can use the hex, oct, and dec manipulators to stipulate that any character sequence input is to processed as a hexadecimal, octal, or decimal number.

Example:

int n;
cin >> oct >> n;

An input value of 10 will be interpreted as an octal, which corresponds to a decimal value of 8.

Example: cin >> hex >> n;

Here, any input will be interpreted as a hexadecimal, enabling input such as f0a or -F7.

□   Inputting Floating-Point Numbers

The >> operator interprets any input as a decimal floating-point number if the variable is a floating-point type, i.e. float, double, or long double. The floating-point num- ber can be entered in fixed point or exponential notation.

Example:

double x;
cin >> x;

The character input is converted to a double value in this case. Input, such as 123,

-22.0, or 3e10 is valid.

□   Input Errors

But what happens if the input does not match the type of variable defined?

Example: int i, j;    cin >> i >> j;

Given input of 1A5 the digit 1 will be stored in the variable i. The next input field begins with A. But since a decimal input type is required, the input sequence will not be processed beyond the letter A. If, as in our example, no type conversion is performed, the variable is not written to and an internal error flag is raised.

It normally makes more sense to read numerical values individually, and clear the input buffer and any error flags that may have been set after each entry.
Chapter 6, “Control Flow,” and Chapter 28, “Exception Handling,” show how a pro- gram can react to input errors.

■ UNFORMATTED INPUT/OUTPUT

Sample program

NOTE:
1.	A text of more than one line can be entered.
2.	The sample program requires that at least one word and a following white space are entered.

Unformatted input and output does not use fields, and any formatting flags that have been set are ignored. The bytes read from a stream are passed to the program “as is.” More specifically, you should be aware that any white space characters preceding the input will be processed.

□   Reading and Writing Characters

You can use the methods get() and put() to read or write single characters. The get() method reads the next character from a stream and stores it in the given char variable.

Example:

char ch;
cin.get(ch);

If the character is a white space character, such as a newline, it will still be stored in the ch variable. To prevent this from happening you can use

cin >> ch;

to read the first non-white space character.

The get() method can also be called without any arguments. In this case, get()

returns the character code of type int.

Example: int c = cin.get();

The put() method can be used for unformatted output of a character. The character to be output is passed to put() as an argument.

Example: cout.put('A');

This statement is equivalent to cout << ‘A’; , where the field width is undefined or has been set to 1.

□   Reading a Line

The >> operator can only be used to read one word into a string. If you need to read a whole line of text, you can use the global function getline(), which was introduced earlier in this chapter.

Example: getline(cin, text);

This statement reads characters from cin and stores them in the string variable text until a new line character occurs. However, you can specify a different delimiting charac- ter by passing the character to the getline() function as a third argument.

Example: getline(cin, s, ‘.’);

The delimiting character is read, but not stored in the string. Any characters subsequent to the first period will remain in the input buffer of the stream.

EXERCISES

Screen output for exercise 3

Article Number Number of Pieces Price per piece . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dollar

Program listing for exercise 5

// A program with resistant mistakes 

#include <iostream>
using namespace std;

int main()
{
    char ch; 
    string word;
 
    cin >> "Let's go! Press the return key: " >> ch; 

    cout << "Enter a word containing
             three characters at most: "; 
    cin >> setprecision(3) >> word;

    cout >> "Your input: " >> ch >> endl;

    return 0;
}
Exercise 1

What output is generated by the program on the page entitled “Formatted output of floating-point numbers” in this chapter?

Exercise 2

Formulate statements to perform the following:

  1. Left-justify the number 0.123456 in an output field with a width of 15.
  2. Output the number 23.987 as a fixed point number rounded to two dec- imal places, right-justifying the output in a field with a width of 12.
  3. Output the number –123.456 as an exponential and with four decimal spaces. How useful is a field width of 10?
Exercise 3

Write a C++ program that reads an article number, a quantity, and a unit price from the keyboard and outputs the data on screen as displayed on the opposite page.

Exercise 4

Write a C++ program that reads any given character code (a positive integer) from the keyboard and displays the corresponding character and the character code as a decimal, an octal, and a hexadecimal on screen

TIP:
The variable type defines whether a character or a number is to be read or output.

Why do you think the character P is output when the number 336 is entered?

Exercise 5

Correct the mistakes in the program on the opposite page.

SOLUTIONS

Exercise 1

Output of a sample program formatting floating-point numbers:

By default: 12
showpoint: 12.
fixed: 12.00
scientific: 1.20e+001

Exercise 2
#include <iostream>
#include <iomanip>	// For setw() and setprecision() 
using namespace std;

int main()
{
    double x1 = 0.123456, x2 = 23.987, x3 = -123.456;
// a)
    cout << left << setw(15) << x1 << endl;
// b)
    cout << fixed << setprecision(2) << right << setw(12)
         << x2 << endl;
// c)
    cout << scientific << setprecision(4) << x3 << endl;
    // Output: -1.2346e+002
    // A field width of 12 or more would be convenient!

    return 0;
}
Exercise 3
// Input and formatted output of article characteristics.
 
#include <iostream>
#include <iomanip> 
using namespace std; 
int main()
{
      long number = 0; 
      int count = 0; 
      double price = 0.0;
                                               // Input:
      cout << "\nPlease enter article characteristics.\n"; 
      cout << "Article number: ";
      cin >> number;
 
      cout << "Number of pieces:	"; 
       cin >> count;

       cout << "Price per piece:	"; 
        cin >> price;

                                                // Output:
       cout <<
       "\n\tArticle Number	Quantity	Price per piece ";

       cout << "\n\t"
            << setw(8)  << number
            << setw(16) << count
            << fixed	<< setprecision(2)
            << setw(16) << price << " Dollar" << endl;

       return 0;
}
Exercise 4
#include <iostream>
#include <iomanip>	// Manipulator setw() 
using namespace std;

int main()
{
   unsigned char c = 0; 
   unsigned int code = 0;

   cout << "\nPlease enter a decimal character code: "; 
   cin >> code;
   c = code;		// Save for output 
   cout << "\nThe corresponding character: " << c << endl; 
   code = c;	// Character code. Is only
                // necessary, if input is > 255.
   cout    << "\nCharacter codes"
           << "\n decimal:	" << setw(3) << dec << code
           << "\n octal:	" << setw(3) << oct << code
           << "\n hexadecimal:  " << setw(3) << hex << code
           << endl;
 
    return 0;
}

When entering 336, the value 80 is stored in the low byte of variable code (336 = 256 + 80).Thus after the assignment, the variable c contains the value 80, representing the character P.

Exercise 5

The corrected program:

// Corrections are commented.

//
#include <iostream>
#include <iomanip>	// Manipulator setw() 
#include <string>	// Class string
using namespace std;

int main()
{
    string word;	// To read a word.
                        // char ch; is not needed.

                        // cout << ...instead of cin >> . 
    cout << "Let's go! Press the return key: ";

    cin.get();	        // Input newline character

    cout << " Enter a word "	                        // "
            "containing three characters at the most: ";// "

    cin >> setw(3) >> word;	       // setw(3) instead of
                                       // setprecision(3)

    cout << "Your input: "	       // <<
         << word << endl;	       // instead of >> ch

    return 0;
}