Home | C++ Tutorial | 6. Common Student Problems |     Share This Page
The skill that makes your computer think

Keyboard Input

Even though this tutorial deals with standard C++, the kind of C++ that is not associated with any particular platform, compiler or hardware, a student can write programs to accept keyboard input and display output, with a reasonable expectation that the program will successfully compile and run in nearly any C++ development environment.

The first page of this section deals with what is probably the most difficult early task students face — successfully gathering keyboard input.

Remember this: a successful program doesn't just read input — it also tests that the input is what the program needs, that it is valid input. This is a principle in all programming — good programs don't just run, they test their inputs, their operations, and their outputs, to assure they meet the program's goals.

C++ has features to help you test your program's input. If you try to accept a number from the keyboard, but the user types non-numeric characters, the input stream will go into an error mode and will provide a signal you may use to detect the error.

Here is our first keyboard program. It is too naïve to detect an error, and it will fail if a non-numeric character is entered:
#include <iostream>

using namespace std;

int main()
{
	int x = 0;
	do {
		cout << "Enter a number (-1 = quit): ";
		cin >> x;
		if(x != -1) {
			cout << "You entered " << x << endl;
		}
	}
	while(x != -1);
	cout << "Quitting program." << endl;
	
	return 0;
}
    
Compile and run this program. Notice that, if you type non-numeric characters, the program fails catastrophically, looping endlessly, printing garbage and no longer responding to keyboard input. This happens because our variable "x" can only contain numbers. If the input stream "cin" detects non-numeric characters, it will go into an error state, and the program will fail.

NOTE: To exit a misbehaving program, one that no longer responds to keyboard input, press Ctrl+C.

Here is a program that represents a slight improvement:
#include <iostream>

using namespace std;

int main()
{
	int x = 0;
	do {
		cout << "Enter a number (-1 = quit): ";
		if(!(cin >> x)) {
			cout << "The input stream broke!" << endl;
			break; // jump out of do ... while
		}
		if(x != -1) {
			cout << "You entered " << x << endl;
		}
	}
	while(x != -1);
	cout << "Quitting program." << endl;
	
	return 0;
}
    
In this version, the program detects the input error, and acts on it. Like all C++ streams, the stream "cin" returns the boolean value "false" if the input operation fails. This program uses the stream's return value to terminate the program.

Note the use of "break" in this version of our program. Experiment with "break," notice that it breaks out of the enclosing braces that define the do ... while control structure.

There is another, perhaps better way to exit our control structure. Can you see what it is? Notice that our do ... while structure always tests for -1. If we set the numeric variable to -1, this will cause this test to succeed and the structure will be existed. Like this:
#include <iostream>

using namespace std;

int main()
{
	int x = 0;
	do {
		cout << "Enter a number (-1 = quit): ";
		if(!(cin >> x)) {
			cout << "The input stream broke!" << endl;
			x = -1; // jump out of do ... while
		}
		if(x != -1) {
			cout << "You entered " << x << endl;
		}
	}
	while(x != -1);
	cout << "Quitting program." << endl;
	
	return 0;
}
    
Don't be afraid to experiment with these sample programs. If there is something you don't understand, or if you have an idea about how something works, test your assumption. You will learn much more, and more quickly, if you perform an experiment on a simple program than if you simply make an assumption without a test.

Repairing the Stream

When an input error is made, the stream "breaks," returns a boolean "false" value, and refuses to function any more. What to do?

The repair process has two parts. First, clear the error:
	cin.clear();
    
This simple step prepares the stream for normal use again. But by itself, "clear()" is not enough.

The second step is more subtle. If the user has typed letters instead of numbers and has broken the stream, the letters are not removed from the stream. They stay in the stream, and they will cause the same failure if they are not removed.

Solution: The program must remove the incorrect characters.

Here is an example that removes the error characters:
#include <iostream>
#include <string>

using namespace std;

int main()
{
	int x = 0;
	string badChars;
	do {
		cout << "Enter a number (-1 = quit): ";
		if(!(cin >> x)) {
			cout << "The input stream broke!" << endl;
			cin.clear();
			cin >> badChars;
			cout << "You typed \"" << badChars << "\" instead of a number." << endl;
			cout << "Please try again." << endl;
		}
		else if(x != -1) {
			cout << "You entered " << x << endl;
		}
	}
	while(x != -1);
	cout << "Quitting program." << endl;
	
	return 0;
}
    
This program works because a string will accept any characters. In case you haven't been reading these tutorial pages in order, the string data type is not a number. It accepts a string of characters — letters, punctuation marks, and numerical digits. It will accept many more kinds of entries than a numeric variable. In this program, it receives the error characters and displays them, the stream is cleared of error characters, and the program can operate again.

If you simply want to throw away the error characters, not use them for anything, do it this way:
cin.ignore(10000,'\n');
    
This statement means "Ignore up to 10000 characters, or until a linefeed is detected, whichever happens first." In C++, the symbol '\n' represents the linefeed character.

Here is a simpler program that throws away the error characters:
#include <iostream>

using namespace std;

int main()
{
	int x = 0;
	do {
		cout << "Enter a number (-1 = quit): ";
		if(!(cin >> x)) {
			cout << "Please enter numeric characters only." << endl;
			cin.clear();
			cin.ignore(10000,'\n');
		}
		else if(x != -1) {
			cout << "You entered " << x << endl;
		}
	}
	while(x != -1);
	cout << "Quitting program." << endl;
	
	return 0;
}
    
There is nothing magic about the number "10000." Just choose a large number. There is actually a maximum-sized number for purposes like this that is built into the C++ standard, but many C++ compilers (including the one I have chosen for this tutorial) do not support it yet.

These pages are Copyright © 2000, P. Lutus. All rights reserved.

www.arachnoid.com Main Page
Home | C++ Tutorial | 6. Common Student Problems |     Share This Page