Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

More about iostreams

So far you have seen only the most rudimentary aspect of the iostreams class. The output formatting available with iostreams also includes features like number formatting in decimal, octal and hex. Here’s another example of the use of iostreams:

//: C02:Stream2.cpp
// More streams features
#include <iostream>
using namespace std;

int main() {
  // Specifying formats with manipulators:
  cout << "a number in decimal: "
       << dec << 15 << endl;
  cout << "in octal: " << oct << 15 << endl;
  cout << "in hex: " << hex << 15 << endl;
  cout << "a floating-point number: "
       << 3.14159 << endl;
  cout << "non-printing char (escape): "
       << char(27) << endl;
} ///:~

This example shows the iostreams class printing numbers in decimal, octal and hexadecimal using iostream manipulators (which don’t print anything, but change the state of the output stream). The formatting of floating-point numbers is determined automatically, by the compiler. In addition, any character can be sent to a stream object using a cast to a char (a char is a data type which holds single characters). This cast looks like a function call: char( ), along with the character’s ASCII value. In the above program, the char(27) sends an “escape” to cout.

Character array concatenation

An important feature of the C preprocessor is character array concatenation. This feature is used in some of the examples in this book. If two quoted character arrays are adjacent, and no punctuation is between them, the compiler will paste the character arrays together into a single character array. This is particularly useful when code listings have width restrictions:

//: C02:Concat.cpp
// Character array Concatenation
#include <iostream>
using namespace std;

int main() {
  cout << "This is far too long to put on a single "
    "line but it can be broken up with no ill effects\n"
    "as long as there is no punctuation separating "
    "adjacent character arrays.\n";
} ///:~

At first, the above code can look like an error because there’s no familiar semicolon at the end of each line. Remember that C and C++ are free-form languages, and although you’ll usually see a semicolon at the end of each line, the actual requirement is for a semicolon at the end of each statement, and it’s possible for a statement to continue over several lines.

Reading input

The iostreams classes provide the ability to read input. The object used for standard input is cin (for “console input”). cin normally expects input from the console, but this input can be redirected from other sources. An example of redirection is shown later in this chapter.

The iostreams operator used with cin is >>. This operator waits for the same kind of input as its argument. For example, if you give it an integer argument, it waits for an integer from the console. Here’s an example:

//: C02:Numconv.cpp
// Converts decimal to octal and hex
#include <iostream>
using namespace std;

int main() {
  int number;
  cout << "Enter a decimal number: ";
  cin >> number;
  cout << "value in octal = 0" << oct << number << endl;
  cout << "value in hex = 0x" << hex << number << endl;
} ///:~

This program converts a number typed in by the user into octal and hexadecimal representations.

Simple file manipulation

Standard I/O provides a very simple way to read and write files, called I/O redirection. If a program takes input from standard input ( cin for iostreams) and sends its output to standard output ( cout for iostreams), that input and output can be redirected. Input can be taken from a file, and output can be sent to a file. To re-direct I/O on the command line of some operating systems (Unix/Linux & DOS, in particular), use the ‘ <’ sign to redirect input and the ‘ >’ sign to redirect output. For example, if we have a fictitious program called fiction that reads from standard input and writes to standard output, you can redirect standard input from the file stuff and redirect the output to the file such with the command:

fiction < stuff > such

Since the files are opened for you, the job is much easier (although you’ll see later that iostreams has a very simple mechanism for opening files).

As a useful example, suppose you want to record the number of times you perform an activity, but the program that records the incidents must be loaded and run many times, and the machine may be turned off, etc. To keep a permanent record of the incidents, you must store the data in a file. This file will be called incident.dat and will initially contain the character 0. For easy reading, it will always contain ASCII digits representing the number of incidents.

The program to increment the number is very simple:

//: C02:Incr.cpp
// Read a number, add one and write it
#include <iostream>
using namespace std;

int main() {
  int num;
  cin >> num;
  cout << num + 1;
} ///:~

To test the program, run it, type a number and press the “Enter” key. The program should print a number one larger than the one you type.

While the typical way to use a program that reads from standard input and writes to standard output is within a Unix shell script or DOS batch file, any program can be called from inside a C or C++ program using the Standard C system( ) function, which is declared in the header file <cstdlib>:

//: C02:Incident.cpp
// Records an incident using INCR
#include <cstdlib> // Declare "system()"
using namespace std;

int main() {
  // Other code here...
  system("incr < incident.dat > incident.dat");
} ///:~

To use the system( ) function, you give it a character array that you would normally type at the operating system command prompt. The command executes and control returns to the program [17].

Notice that the file incident.dat is read and written using I/O redirection. Since the single ‘ >’ is used, the file is overwritten. Although it works fine here, reading and writing the same file isn’t always a safe thing to do – if you aren’t careful you can end up with garbage in the file.

If a double ‘ >>’ is used instead of a single ‘ >’, the output is appended to the file (and this program wouldn’t work correctly).

This program shows you how easy it is to use plain C library functions in C++: just include the header file and call the function. This upward compatibility from C to C++ is a big advantage if you are learning the language starting from a background in C.


[17] If you find yourself writing programs that use a lot of system( ) calls, you might be more productive using the Perl language instead.

Contents | Prev | Next


Contact: webmaster@codeguru.com
CodeGuru - the website for developers.
[an error occurred while processing this directive]