Posted by: Ben Rubenstein
Addison-Wesley, Book excerpt, C++, Developers, Programming
The following is an excerpt from C++ Primer, Fifth Edition, by Stanley B. Lippman, Josee Lajoie and Barbara E. Moo, available from Addison-Wesley Professional.
For more information, read Jaideep Khanduja’s review of the full book.
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:
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;
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
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
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 7 Sectio n 1. 2 A Firs t Loo k a t Input/Outpu t
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. 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)tosay 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:
intv1 = 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.