开发者

How can I break out of my do/while loop?

void GasPump::dispense()
{

        bool cont = true;
        char stop;

    do{
        cout << "Press any key, or enter to dispense.\n"
             << "Or press 0 to stop: \n";
        cin.get(stop);

        gasDispensed = gasDispensed + gasDispensedPerCycle;
        charges = costPerGallon*gasDispensed;
        displayGasNCharges();

        if(stop == 0)
            cont = false;

    } while(cont);

}

Doing an assignment, this is my first program to write with objects so bear with me. I just can't get the output of this code to turn out ri开发者_开发百科ght. I need a way to get out of the loop, and what I'm using just isn't working. Any suggestions, hints or tips?


Try comparing stop to the zero char.

stop == '0'

Also you can simplify your code by doing this.

void GasPump::dispense()
{
    char stop;

    do {
        cout << "Press any key, or enter to dispense.\n"
             << "Or press 0 to stop: \n";
        cin.get(stop);

        gasDispensed = gasDispensed + gasDispensedPerCycle;
        charges = costPerGallon*gasDispensed;
        displayGasNCharges();
    } while (stop != '0');
}


In this scenario, you pump gas one extra time after the user hits '0'. Assuming that this is not desired, you have what is known as an "off-by-one error." You can fix this (and eliminate the temporary variable) by rearranging your function as follows:

void GasPump::dispense()
{
    while (true) {
        cout << "Press any key, or enter to dispense.\n"
             << "Or press 0 to stop: \n";

        if (cin.get() == '0')
            break;

        gasDispensed = gasDispensed + gasDispensedPerCycle;
        charges = costPerGallon*gasDispensed;
        displayGasNCharges();
    }
}

To avoid using a break statement, you can use the following construction:

bool GasPump::shouldDispenseGas()
{
    cout << "Press any key, or enter to dispense.\n"
         << "Or press 0 to stop: \n";
    return (cin.get() != '0');
}

void GasPump::dispense()
{
    while (shouldDispenseGas()) {
        gasDispensed = gasDispensed + gasDispensedPerCycle;
        charges = costPerGallon*gasDispensed;
        displayGasNCharges();
    }
}

EDIT (2011 September 27): @TonyK Just because a language provides a feature doesn't mean that one should use it. The goto statement is a classic example of this.

Granted, with such a simple loop, there's really no difference between using a function and the break. Both are clear. However, when extra features get added a month (or years) later, along with extra conditions for breaking out of the loop, it's very easy to find multiply-nested if statements with complex logic inside a loop that's so large, you have a hard time finding its beginning, much less the exit points. One of the ways to fight this type of code bloat is to write short, simple, and focused functions that are well-named. If you do this, the code documents itself. Compare

while (true)

versus

while (shouldDispenseGas())

Similarly, compare this to the STL for_each algorithm. Sure, std::for_each(v.begin(), v.end(), &foo); is a little shorter than for (int i = 0; i < v.size(); ++i) { ...body of foo()... }. But the real advantage is that it's easier to see what the intent is. In the for_each you immediately see that you will be doing something once, and only once, to each element. In the for loop, you have no idea. The loop counter i may be changed in the loop. A break may be hidden inside as well. By shirking this break statement and embedding the logic in shouldDispenseGas, you immediately understand the conditions under which the loop will continue, and end.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜