This appendix is primarily for students with a background in C programming, but with little or no C++ programming. In the appendix we provide details of the C++ approach to reading from standard input, writing to standard output, and reading/writing files.
The i nsertion operator (written << ) is used to write a value to an output stream such as the standard output device (usually the monitor screen). For example, if i is an integer variable, then the following statement writes its value to the standard output:
In this statement, cout stands for the "console output," and is defined as part of the header file iostream.h . You may write several items at once by chaining together a sequence of insertion operators. For example, if i , j , and k are integer variables, then the following statement first writes i , then j , and finally k to the standard output:
There are two ways to write the end of a line to an output stream. You may simply write the newline character '\n' , or you may write the special object called endl (which is part of iostream.h ). For example:
What's the difference between these two statements? The main difference deals with the fact that output is often written to a special place called a buffer, rather than to the actual output device. When the buffer becomes full, the output is "flushed" from the buffer to the actual output device. Such buffering can cause problems if a program crashes before the buffer is flushed. The buffer may contain some output that never shows up on the output device. To avoid this problem, whenever you write the endl object, the output buffer is automatically flushed. However, simply writing the newline character does not automatically flush the output buffer.
The field width of an output item is the preferred number of output characters to be used when the item is printed. For example, if you print the number 123 with a field width of eight, the result will be five blank spaces followed by the digits 123 for a total of eight characters. If the output item won't fit in the specified field width, then more characters may be used. For example, if you print the number 123 with a field width of only two, then the entire number 123 is still printed (even though this requires three characters rather than just two). If you define the field width to be zero, the item will be printed using the minimum possible number of characters.
How do you define the field width for an output item? One method is to use a special "manipulator" named setw , which is part of iomanip.h . The setw manipulator is called like a function, with one argument that is the desired field width. This manipulator is placed in the output statement just before the item to be printed. For example, to print the number 123 with a field width of eight, you may write the statement:
When output occurs with a wide field width, each output item is padded with spaces to bring the total number of characters up to the required field width. For example, when the number 123 is printed with a field width of eight, the complete output will consist of five spaces followed by the three digits of 123 . If you don't specify otherwise, the item is printed on the far right of the field width, with any padding spaces before the item. You can control the placement of the item by calling the setf function to set the "control flags" of an output device such as cout . This function is called with the syntax shown in these three examples:
Once the justification is set with the setf function, it remains in effect for all subsequent outputs until it is reset to some other value. The ios::internal setting causes numbers to be printed with the + or - sign as the first output character, but the remainder of the number appears on the right side of the field width. (In order to force a number to be printed with a + sign, you will have to call cout.setf(ios::showpos) ; When you no longer want the + signs to print, you may call cout.unsetf(ios::showpos) .)
By the way, you can see that setf and unsetf are both member functions of the cout output stream. They are defined in iostream.h and may be used with any output stream. The arguments, such as ios::left , are also defined in the header file iostream.h .
The first example, using ios::fixed , causes numbers to be printed in fixed-point notation, which is the common way of writing numbers with a decimal point. For example, the number 19 will be printed as 19.25 .
The second example, using ios::scientific , causes numbers to be printed in scientific notation consisting of a number times some power of ten. For example, the large number 1.8 10 16 will be printed as 1.8e16 . The letter e indicates the exponent.
(An alternative is , using setprecision from iomanip.h .) With a precision of 12, the fixed-point and scientific notations will both have 12 digits of accuracy after the decimal point. The automatic notation will have a total of 12 significant digits. Once you set the precision, it stays in effect for all subsequent outputs.
When the fixed-point notation is used, trailing zeros and the decimal point are not always printed. For example, the double number 123.0 will be printed as 123 (with no decimal point). With a precision of 12, the number 19 will be printed with no trailing zeros, resulting in 19.25 (rather than 19.250000000000 ). You may force the decimal point and trailing zeros for fixed-point numbers with the function call cout.setf(ios::showpoint) . You may revert to the usual method of fixed-point numbers with the function call cout.unsetf(ios::showpoint) . As usual, these functions may be used with any output stream (not just with cout ).
The extraction operator (written >> ) is used to read a value from an input stream such as the standard input device (usually the keyboard). For example, if i is an integer variable, then the following statement reads an integer value from the standard input, and stores the result in i :
In this statement, cin stands for the "console input," and is defined as part of the header file iostream.h . You may read several items at once by chaining together a sequence of extraction operators. For example, if i , j , and k are integer variables, then the following statement first reads i , then j , and finally k from the standard input:
In this case, the extraction operator skips any initial white space and reads characters into message until more white space is encountered. For example, suppose that the program's user types the following input line (followed by the return key):
The statement cin >> message will skip any initial white space, read the characters The --ending when the blank is encountered after the e. The blank itself is not read. The three characters that were read are placed in message , with a null terminator after the third character. There is no checking to ensure that the array is large enough to hold the characters that were read.
Sometimes a user provides illegal data for an input operation. For example, the program might be reading an integer, but the user types the word quick. Whenever bad data is encountered, the input stream is marked as bad input. Once the input stream is bad, any subsequent attempts to read from the input stream will have no effect! Nothing is read, no variable values are assigned.
You may use the name of an input stream as a boolean expression to test whether the stream is bad. A bad stream results in a false expression; a device that is still good results in a true expression. For example:
Many other input functions are part of iostream.h . We'll describe three of the most useful functions. The first function, called get , has several forms, including a form that simply reads the next input character. For example, suppose that c is a character variable. The following statement reads the next character from the standard input, and assigns the read value to c :
Notice that get is called as a member function of the cin object. How does differ from ? The answer is that get always reads the next character without skipping white space; on the other hand, the >> operator skips white space before reading the next character.
Another member function, called peek , allows you to look at the next available character without actually reading it. For example, the following code checks to see whether the next character is the letter 'X' :
The peek function always returns the next input character without skipping white space. As another example, this code will read and discard characters until the input stream becomes bad, or a newline character is reached:
Here is one more example of a function that reads and discards characters until the input stream becomes bad or a non-white space character is reached. The function makes use of a boolean function, called isspace , to determine whether a character is white space:
It is possible for the standard input to be connected to a file of characters. In this case, a program must be able to detect when the end of the input file has been reached. When the last actual character of the file has been read, the peek function returns a special constant named EOF (which is part of iostream.h ). For example:
One warning: The peek function does not return the EOF constant until all characters of the file have been read--including any blanks or newline characters that may appear after the last piece of actual data. For example, suppose that the standard input is a file of integers. We want to read and add up all these integers until the end of file is reached. The correct way to process the input file is shown here (using the eat_white function, written above):
So far, we have shown output and input using the standard streams cout and cin . A program can also create its own streams, connecting these streams to files. Such a program must include both iostream.h and fstream.h , and proceed as follows:
For writing, a program should declare a variable of type ofstream . For reading, a program should declare a variable of type ifstream . Once the variable is declared, it can be connected to an actual file with the open member function, as shown here:
The argument to the open function is the name of the file that you wish to write. In our output example, this argument is the constant string "results" , so we will be writing a file named results . Our input example is reading text from a file named data . The argument to the open function may also be a string variable, or any other string expression.
Sometimes, when you open a file, the open operation fails. For example, opening a file for writing can fail if the computer's disk is already full. Opening a file for input will fail if the specified file cannot be found. If the open operation fails, then the stream will be marked as "bad." You may use the name of a stream as a boolean expression to test whether the stream is bad. A bad stream results in a false expression; a device that is still good results in a true expression. Thus, after opening a file, you should check for possible failure. A simple approach uses the assert function (from assert.h ), as shown here:
Once an ifstream is open, you may use it in the same way that you have used cin . For example, suppose that infile (opened above) contains lines of digits. You can read the next integer in the input file, storing the result in an integer variable i , as shown here: