1.2. A First Look at Input/Output
The C++ language does not define any statements to do input or output (IO). Instead, C++ includes an extensive standard library that provides IO (and many other facilities). For many purposes, including the examples in this book, one needs to know only a few basic concepts and operations from the IO library.
Most of the examples in this book use the iostream
library. Fundamental to the iostream
library are two types named istream
and ostream
, which represent input and output streams, respectively. A stream is a sequence of characters read from or written to an IO device. The term stream is intended to suggest that the characters are generated, or consumed, sequentially over time.
Standard Input and Output Objects
The library defines four IO objects. To handle input, we use an object of type istream
named cin
(pronounced see-in). This object is also referred to as the standard input. For output, we use an ostream
object named cout
(pronounced see-out). This object is also known as the standard output. The library also defines two other ostream
objects, named cerr
and clog
(pronounced see-err and see-log, respectively). We typically use cerr
, referred to as the standard error, for warning and error messages and clog
for general information about the execution of the program.
Ordinarily, the system associates each of these objects with the window in which the program is executed. So, when we read from cin
, data are read from the window in which the program is executing, and when we write to cout
, cerr
, or clog
, the output is written to the same window.
A Program That Uses the IO Library
In our bookstore problem, we’ll have several records that we’ll want to combine into a single total. As a simpler, related problem, let’s look first at how we might add two numbers. Using the IO library, we can extend our main
program to prompt the user to give us two numbers and then print their sum:
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;
return 0;
}
This program starts by printing
Enter two numbers:
on the user’s screen and then waits for input from the user. If the user enters
3 7
followed by a newline, then the program produces the following output:
The sum of 3 and 7 is 10
The first line of our program
#include <iostream>
tells the compiler that we want to use the iostream
library. The name inside angle brackets (iostream
in this case) refers to a header. Every program that uses a library facility must include its associated header. The #include
directive must be written on a single line—the name of the header and the #include
must appear on the same line. In general, #include
directives must appear outside any function. Typically, we put all the #include
directives for a program at the beginning of the source file.
Writing to a Stream
The first statement in the body of main
executes an expression. In C++ an expression yields a result and is composed of one or more operands and (usually) an operator. The expressions in this statement use the output operator (the «
operator) to print a message on the standard output:
std::cout << "Enter two numbers:" << std::endl;
The <<
operator takes two operands: The left-hand operand must be an ostream
object; the right-hand operand is a value to print. The operator writes the given value on the given ostream
. The result of the output operator is its left-hand operand. That is, the result is the ostream
on which we wrote the given value.
Our output statement uses the <<
operator twice. Because the operator returns its left-hand operand, the result of the first operator becomes the left-hand operand of the second. As a result, we can chain together output requests. Thus, our expression is equivalent to
(std::cout << "Enter two numbers:") << std::endl;
Each operator in the chain has the same object as its left-hand operand, in this case std::cout
. Alternatively, we can generate the same output using two statements:
std::cout << "Enter two numbers:";
std::cout << std::endl;
The first output operator prints a message to the user. That message is a string literal, which is a sequence of characters enclosed in double quotation marks. The text between the quotation marks is printed to the standard output.
The second operator prints endl
, which is a special value called a manipulator. Writing endl
has the effect of ending the current line and flushing the buffer associated with that device. Flushing the buffer ensures that all the output the program has generated so far is actually written to the output stream, rather than sitting in memory waiting to be written.
WARNING
Programmers often add print statements during debugging. Such statements should always flush the stream. Otherwise, if the program crashes, output may be left in the buffer, leading to incorrect inferences about where the program crashed.
Using Names from the Standard Library
Careful readers will note that this program uses std::cout
and std::endl
rather than just cout
and endl
. The prefix std::
indicates that the names cout
and endl
are defined inside the namespace named std
. Namespaces allow us to avoid inadvertent collisions between the names we define and uses of those same names inside a library. All the names defined by the standard library are in the std
namespace.
One side effect of the library’s use of a namespace is that when we use a name from the library, we must say explicitly that we want to use the name from the std
namespace. Writing std::cout
uses the scope operator (the ::
operator) to say that we want to use the name cout
that is defined in the namespace std
. § 3.1 (p. 82) will show a simpler way to access names from the library.
Reading from a Stream
Having asked the user for input, we next want to read that input. We start by defining two variables named v1
and v2
to hold the input:
int v1 = 0, v2 = 0;
We define these variables as type int
, which is a built-in type representing integers. We also initialize them to 0
. When we initialize a variable, we give it the indicated value at the same time as the variable is created.
The next statement
std::cin >> v1 >> v2;
reads the input. The input operator (the »
operator) behaves analogously to the output operator. It takes an istream
as its left-hand operand and an object as its right-hand operand. It reads data from the given istream
and stores what was read in the given object. Like the output operator, the input operator returns its left-hand operand as its result. Hence, this expression is equivalent to
(std::cin >> v1) >> v2;
Because the operator returns its left-hand operand, we can combine a sequence of input requests into a single statement. Our input operation reads two values from std::cin
, storing the first in v1
and the second in v2
. In other words, our input operation executes as
std::cin >> v1;
std::cin >> v2;
Completing the Program
What remains is to print our result:
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;
This statement, although longer than the one that prompted the user for input, is conceptually similar. It prints each of its operands on the standard output. What is interesting in this example is that the operands are not all the same kinds of values. Some operands are string literals, such as "The sum of "
. Others are int
values, such as v1
, v2
, and the result of evaluating the arithmetic expression v1 + v2
. The library defines versions of the input and output operators that handle operands of each of these differing types.
INFO
Exercises Section 1.2
Exercise 1.3: Write a program to print Hello, World
on the standard output.
Exercise 1.4: Our program used the addition operator, +
, to add two numbers. Write a program that uses the multiplication operator, *
, to print the product instead.
Exercise 1.5: We wrote the output in one large statement. Rewrite the program to use a separate statement to print each operand.
Exercise 1.6: Explain whether the following program fragment is legal.
std::cout << "The sum of " << v1;
<< " and " << v2;
<< " is " << v1 + v2 << std::endl;
If the program is legal, what does it do? If the program is not legal, why not? How would you fix it?