CS 12 - Lab 1 Supplement
CS 12
Homepage
Streams: True or False?
So you may be wondering how to write a program that takes in all
inputs and yet still knows when to quit. What input do you give it to
tell it to quit? Won't we just wind up in an infinite loop?
Let us look at some other programs that do similar things. Try
running the Unix program wc (short for word count), a program
that counts the number
of words, lines, and characters you type (or in a file if you specify
one.)
> wc
testing testing one two three
hello, this is a test
is anybody home?
quit
exit
stop
EXIT
Nothing we type seems to be terminating the program. If we read the
man page for wc, we will see that it expects to run until there is no
more input. So the question is how to we specify to wc that there is
no more input, and then how to we use that in our program?
The secret is actually one simple key combination: Ctrl+D. Ctrl+D
(also written as ^D) tells the operating system "I am done typing, I
will not give this program any further input." The operating system
then informs the program that you are done by closing off the input to
the program, which the program can then notice and terminate on its
own. Try it on wc and see that it does actually work.
The natural question is then this: how do we write a program that can
notice when the input to the program has been closed? Look back at
the title of this section, and try to remember how I/O in C++ works.
(If you don't recall the CS10 lectures on "streams", don't worry too
much. If you do, think back to them, it'll help you some
here.)
When the input to your program is closed, cin can never
give you anything of use. The people that wrote the I/O libraries for
C++ know this, and took advantage of it. If you happen to test the
truth value of cin (like in an if statement or a loop conditional),
then cin will return true if input is still open or false if the input
is closed.
Let's look at an example snippet of code (you can fill in the rest of
the code as needed if you want to see this compile in action):
// While the input is still open
while(cin)
{
// Get the input
cin >> myinput;
cout << "Got " << myinput << endl;
// Process the input
...
}
What happens when we run this? (Every other line is input to the
program and output from the program):
hello
Got hello
42
Got 42
camera
Got camera
^D
Got camera
Why did it do that? We didn't type "camera" twice. Examine the loop,
bit by bit, remembering that unless we are insanely fast typists, the
program is always waiting at the cin statement for more input (it
takes maybe a thousandth of a second to execute the rest of the
loop). When we hit ^D, cin is told to terminate and not return
anything, so our variable does not get changed, and the loop has to
continue until we check the looping condition again. Which explains
why we get the bogus output.
So lets try something a little sneaky. Let's make sure that we get
the input right before we check the looping condition. Try
this:
cin >> myinput;
while (cin)
{
cout << "Got " << myinput << endl;
// Process the input
...
cin >> myinput;
}
Now every time that we are waiting for input from cin, we immediately
check the loop condition right afterward, and can terminate
appropriately. This technique will help you both in this lab and in
your first programming project. Keep it in mind in the future, it
can be very helpful.
But it turns out we can do even better than this. istream >> has
been written to return "false" when a read fails. So the code
while (cin >> myinput)
{
// Process the input
...
}
also works correctly, and is even easier to remember, so long as you remember
that streams return false when a read fails.
© 2003 UC Riverside Department of Computer Science &
Engineering. All rights reserved.