1.8. C++ Console Input / Output

Time: 00:05:32 | Download: Large, Large (CC), Small | Streaming, Streaming (CC) | Slides (PDF)

Few programs are useful without the ability to input the data upon which they operate and output those operations' results. Modern computers support input and output through an interactive graphical user interface (GUI). However, older systems were strictly text-based (CLI). For simplicity, we begin our discussion with the text-based I/O system called the console.

The Computer Console

The most basic C++ input and output (I/O) operations are to and from the console. The first console was a teletype machine, which was originally developed for and used to send messages similar to today's e-mail. The Cathode ray tube (CRT) eventually replaced the teletype as a computer's primary output device. Initially, CRTs could display text but not windows or, until much later, graphics.

A picture of an old computer with a CRT screen and a keyboard.
The computer console. In the '60s, '70s, and early '80s, the console was the computer screen and the keyboard. There were no windows on the screen at this time.

Although the console is not as appealing or intuitive as a GUI, the console remains an important user interface (UI). On modern systems, the console takes one of two forms. The first form is just as it appeared in the pre-GUI days. We often see this console version before the operating system starts the GUI. This version is also the only interface available on some server operating systems (Ubuntu Server, e.g.) that omit the GUI to avoid its overhead. Windows users' systems will see this console if they pres F8 early in the boot process or if the system encounters a problem while shutting down. We'll see the second form when running C++ programs from an IDE. Some IDEs automatically open a text-based window when running a program; other IDEs provide the same text-based I/O operations in a panel displayed in the IDE window itself. Users can also open a console window directly by running one of many console programs: command prompt, power shell, bash (Bourne again shell), etc. This section introduces several C++ features that support console I/O and related concepts.

I/O Objects

The C++ library contains several stream objects through which it can perform console I/O operations. The I/O objects represent data as streams or sequences of bytes (i.e., characters) as they enter or leave the running program. The following figure illustrates the three most common stream objects: cin, cout, and cerr. The "c" appearing in the name of each object stands for "console." All console objects send data to and receive data from the console. A modern console consists of the keyboard and the screen or the console window when running a GUI. As depicted in the illustration below, input comes from the keyboard through cin, and "normal" output is sent to the screen through cout. Programs often send error messages or diagnostics to the screen through cerr. C++ uses two output streams so that the user can separate them with console operators and send the two streams to different destinations when desired.

An abstract picture of a running program: An arrow labeled cin represents data input to the program from the keyboard. Arrows labeled 'cout' and 'cerr' represent data output from the program to a console window on the computer screen.
A running program with three console I/O streams. A modern console consists of a keyboard and a window on a computer screen. cin (console in), cout (console out), and cerr (console error) are stream objects that become part of every C++ program. The console objects channel streams of bytes to and from running programs. cout and cerr are directed to the same console window by default, but it is possible to separate the two streams and send them to different destinations. Reading data from or writing data to the console involves some overhead. Each stream object has a buffer that temporarily holds the data as it moves between the program and console, improving run-time efficiency. Modern computer hardware systems have machine instructions for moving large data blocks en masse. So, it's more efficient to buffer or "save up" the data, reducing the number of move operations.

cin is an instance of a class named istream, while cout and cerr are instances of of a class named ostream. C++ saves the three stream objects in a library, and the linker/loader extracts them and incorporates them in programs as needed. Whenever our program needs to use a library feature, the program must describe it, or, more formally, declare it. We typically supply this information by #including a header file at the top of the C++ source code file.

#include <iostream>
using namespace std;
	.
	.
	.
cout << "hello world" << endl;
#include <iostream>
	.
	.
	.
std::cout << "hello world" << std::endl;
 
(a)(b)
Accessing the I/O system. The iostream header file describes C++'s I/O library features, allowing a program to access and use them.
  1. The using statement allows a convenient shorthand notation but is not strictly necessary. The name std is a namespace, which is similar to a Java package. This observation implies that the C++ using statement is similar to Java's import statement: both allow a program to use a library feature without naming its full path.
  2. Without the using statement, the program can still access the library features by providing a complete name to them. The binary scope resolution operator, ::, has two operands. The left-hand operand names a structure, like a namespace, controlling a feature's scope. The right-hand operand names the library feature. This example illustrates code accessing and using cout and endl with the scope resolution operator.
Note that the preprocessor directive #include does not end with a semicolon, while the using statement does.

cin, cout, and cerr are stream objects, supporting numerous functions. Programs access many of those functions with the dot operator just like the methods in a Java program. However, other functions have a rather unusual syntax that is quite different from Java's. These special functions take one of two forms: operators or manipulators.

I/O Operations

C++ has another feature that has no analog in Java: overloaded operators. Operators are, as we will see in greater detail later, just functions, but they are functions that support a novel calling syntax. Most of our initial experience with operators center on the << (inserter or output) operator and the >> (extractor or input) operator. These two operators work in conjunction with cout, cerr, and cin to write data out from or read data into a program:

cout << "Hello world" << endl;    // data output
cin >> counter;                   // data input
An example of C++ I/O. Together, cout and << provide the basic C++ output operation. In this context, << is called the inserter operator. Similarly, cin and >> provide the basic C++ input operation. In this context, >> is called the extractor operator.
<< inserts data into the output stream while >> extracts data from the input stream. Think of the arrows as pointing in the direction the data flows when compared to the I/O objects and the program.

The example above also uses a manipulator. Manipulators are also special functions designed to work with either the << (inserter) or the >> (extractor) operator. The endl manipulator (the last character is a lower-case 'L') inserts an end-of-line and flushes the output buffer (i.e., it forces the output stream to send the buffer's contents to the console even if the buffer isn't full). The end-of-line causes the cursor (a symbol indicating where the console will display the next character) to drop down one line and return to the left side of the screen (i.e., console window). The following example demonstrates the endl manipulator:

#include <iostream>
using namespace std;

int main()
{
	cout << "See the quick red ";
	cout << "fox jump over the ";
	cout << "lazy brown dog." << endl;

	cout << endl;

	cout << "See the quick red " << endl;
	cout << "fox jump over the " << endl;
	cout << "lazy brown dog." << endl;

	return 0;
}

Program output:

See the quick red fox jump over the lazy brown dog.

See the quick red
fox jump over the
lazy brown dog.
An example of the endl manipulator. Whenever the inserter processes an endl in an output statement, it inserts the end-of-line character. endl often appears at the end of an output statement, but we can place it anywhere in the statement any number of times.

Note:

If you remember that endl is short for end-line, it's easy to remember that the last character in endl is a lower-case 'L'

Escape Sequences

Sometimes, when writing programs, especially when sending output to the screen, programmers often need to reference characters without a clear, visible representation or characters with special meaning within a program. Both C++ and Java use a special sequence of characters, called an escape sequence, to denote these characters and distinguish them from other programming elements. Each of the escape sequences in the following table begins with \, which is called the escape character. Note that different devices may respond differently to a specific escape sequence.

Sequence Character Description
\n Newline The newline or ASCII linefeed character; similar in effect to endl but doesn't flush the output buffer;
cout << "Hello world\n";
\a Alert Makes an audible sound
\b Backspace Moves the cursor back one space
\f Form-feed Also known as a page separator
\r Carriage Return Similar to the newline on some systems
\t Tab Horizontal tab
\\ Backslash Print a \ character: cout << "\\" << endl;
\' Single Quotation Mark Make a character out of a single quotation mark: '\''
\" Double Quotation Mark Embed a double quotation mark in a string: cout << "I said, \"Hello!\""
\xdd Hexadecimal Character Used to form any 8-bit character; often used to represent control or extended-ASCII characters: '\x0A' is the newline character, '\x41' is a upper-case 'A', and '\x9C' is the British pound symbol: £
Escape sequences. Programs use escape sequences to embed special characters inside strings (often for output) and make single characters (often for testing). Visually, escape sequences consist of two or more characters or keystrokes, but they represent a single character). For example, '\\' represents a single backslash character.