Program Notes

Note that whereas the continue statement causes the program in Listing 6.12 to skip the rest of the loop body, it doesn’t skip the loop update expression. In a for loop, the continue statement makes the program skip directly to the update expression and then to the test expression. For a while loop, however, continue makes the program go directly to the test expression. So any update expression in a while loop body following the continue would be skipped. In some cases, that could be a problem.

This program doesn’t have to use continue. Instead, it could use this code:

if (line[i] == ' ')
    spaces++;

However, the continue statement can make a program more readable when several statements follow the continue. That way, you don’t need to make all those statements part of an if statement.

C++, like C, also has a goto statement. A statement like this means to jump to the location bearing the paris: label:

goto paris;

That is, you can have code like this:

char ch;
cin >> ch;
if (ch == 'P')
      goto paris;
cout << ...
...
paris: cout << "You've just arrived at Paris. ";

In most circumstances (some would say in all circumstances), using goto is a bad hack, and you should use structured controls, such as if else, switch, continue, and the like, to control program flow.

Number-Reading Loops

Say you’re preparing a program to read a series of numbers into an array. You want to give the user the option to terminate input before filling the array. One way to do this is utilize how cin behaves. Consider the following code:

int n;
cin >> n;

What happens if the user responds by entering a word instead of a number? Four things occur in such a mismatch:

• The value of n is left unchanged.

• The mismatched input is left in the input queue.

• An error flag is set in the cin object.

• The call to the cin method, if converted to type bool, returns false.

The fact that the method returns false means that you can use non-numeric input to terminate a number-reading loop. The fact that non-numeric input sets an error flag means that you have to reset the flag before the program can read more input. The clear() method, which also resets the end-of-file (EOF) condition (see Chapter 5), resets the bad input flag. (Either bad input or the EOF can cause cin to return false. Chapter 17, “Input, Output, and Files,” discusses how to distinguish between the two cases.) Let’s look at a couple examples that illustrate these techniques.

Say you want to write a program that calculates the average weight of your day’s catch of fish. There’s a five-fish limit, so a five-element array can hold all the data, but it’s possible that you could catch fewer fish. Listing 6.13 uses a loop that terminates if the array is full or if you enter non-numeric input.

Listing 6.13. cinfish.cpp


// cinfish.cpp -- non-numeric input terminates loop
#include <iostream>
const int Max = 5;
int main()
{
    using namespace std;
// get data
    double fish[Max];
    cout << "Please enter the weights of your fish. ";
    cout << "You may enter up to " << Max
            << " fish <q to terminate>. ";
    cout << "fish #1: ";
    int i = 0;
    while (i < Max && cin >> fish[i]) {
        if (++i < Max)
            cout << "fish #" << i+1 << ": ";
    }
// calculate average
    double total = 0.0;
    for (int j = 0; j < i; j++)
        total += fish[j];
// report results
    if (i == 0)
        cout << "No fish ";
    else
        cout << total / i << " = average weight of "
            << i << " fish ";
    cout << "Done. ";
    return 0;
}



Note

As mentioned earlier, some execution environments require additional code to keep the window open so that you can see the output. In this example, because the input 'q' turns off further input, the treatment is more elaborate:


if (!cin)  // input terminated by non-numeric response
{
    cin.clear();  // reset input
    cin.get();    // read q
}
cin.get();        // read end of line after last input
cin.get();        // wait for user to press <Enter>

You also could use code similar to this in Listing 6.13 if you wanted the program to accept more input after exiting the loop.

Listing 6.14 further illustrates using the cin return value and resetting cin.


The expression cin >> fish[i] in Listing 6.13 is really a cin method function call, and the function returns cin. If cin is part of a test condition, it’s converted to type bool. The conversion value is true if input succeeds and false otherwise. A false value for the expression terminates the loop. By the way, here’s a sample run of the program:

Please enter the weights of your fish.
You may enter up to 5 fish <q to terminate>.
fish #1: 30
fish #2: 35
fish #3: 25
fish #4: 40
fish #5: q
32.5 = average weight of 4 fish
Done.

Note the following line of code:

while (i < Max && cin >> fish[i]) {

Recall that C++ doesn’t evaluate the right side of a logical AND expression if the left side is false. In such a case, evaluating the right side means using cin to place input into the array. If i does equal Max, the loop terminates without trying to read a value into a location past the end of the array.

The preceding example doesn’t attempt to read any input after non-numeric input. Let’s look at a case that does. Suppose you are required to submit exactly five golf scores to a C++ program to establish your average. If a user enters non-numeric input, the program should object, insisting on numeric input. As you’ve seen, you can use the value of a cin input expression to test for non-numeric input. Suppose the program finds that the user enters the wrong stuff. It needs to take three steps:

1. Reset cin to accept new input.

2. Get rid of the bad input.

3. Prompt the user to try again.

Note that the program has to reset cin before getting rid of the bad input. Listing 6.14 shows how these tasks can be accomplished.

Listing 6.14. cingolf.cpp


// cingolf.cpp -- non-numeric input skipped
#include <iostream>
const int Max = 5;
int main()
{
    using namespace std;
// get data
    int golf[Max];
    cout << "Please enter your golf scores. ";
    cout << "You must enter " << Max << " rounds. ";
    int i;
    for (i = 0; i < Max; i++)
    {
        cout << "round #" << i+1 << ": ";
        while (!(cin >> golf[i])) {
            cin.clear();     // reset input
            while (cin.get() != ' ')
                continue;    // get rid of bad input
            cout << "Please enter a number: ";
        }
    }
// calculate average
    double total = 0.0;
    for (i = 0; i < Max; i++)
        total += golf[i];
// report results
    cout << total / Max << " = average score "
            << Max << " rounds ";
    return 0;
}


Here is a sample run of the program in Listing 6.14:

Please enter your golf scores.
You must enter 5 rounds.
round #1: 88
round #2: 87
round #3: must i?
Please enter a number: 103
round #4: 94
round #5: 86
91.6 = average score 5 rounds

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.105.215