Как я могу выйти из своего цикла do / while?

StackOverflow https://stackoverflow.com/questions/2346189

  •  23-09-2019
  •  | 
  •  

Вопрос

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);

}

Выполняя задание, это моя первая программа, написанная с использованием объектов, так что потерпите меня.Я просто не могу добиться, чтобы результат этого кода получился правильным.Мне нужен способ выйти из цикла и то, что я использую, просто не работает.Есть какие-нибудь предложения, намеки или подсказки?

Это было полезно?

Решение

Попробуйте сравнить stop с нулевым символом.

stop == '0'

Также вы можете упростить свой код, сделав это.

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');
}

Другие советы

В этом сценарии вы закачиваете газ еще один раз после того, как пользователь нажмет "0".Предполагая, что это нежелательно, вы получаете так называемую "одноразовую ошибку". Вы можете исправить это (и устранить временную переменную), изменив свою функцию следующим образом:

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();
    }
}

Чтобы избежать использования инструкции break, вы можете использовать следующую конструкцию:

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();
    }
}

РЕДАКТИРОВАТЬ (27 сентября 2011):@TonyK Просто потому, что язык предоставляет функцию, не означает, что его следует использовать.В goto утверждение является классическим примером этого.

Конечно, при таком простом цикле на самом деле нет никакой разницы между использованием функции и разрывом.И то, и другое ясно.Однако, когда дополнительные функции добавляются месяц (или годы) спустя вместе с дополнительными условиями для выхода из цикла, очень легко найти многозадачность if инструкции со сложной логикой внутри цикла, который настолько велик, что вам трудно найти его начало, не говоря уже о точках выхода.Один из способов борьбы с этим типом раздувания кода - писать короткие, простые и целенаправленные функции с правильными названиями.Если вы сделаете это, код документирует сам себя.Сравнить

while (true)

против

while (shouldDispenseGas())

Аналогично, сравните это с STL for_each алгоритм.Конечно, std::for_each(v.begin(), v.end(), &foo); немного короче , чем for (int i = 0; i < v.size(); ++i) { ...body of foo()... }.Но реальное преимущество заключается в том, что так легче понять, в чем заключается намерение.В for_each вы сразу видите, что будете делать что-то один и только один раз с каждым элементом.В цикле for вы понятия не имеете.Счетчик циклов i может быть изменен в цикле.A break также может быть спрятан внутри.Уклоняясь от этого break утверждение и встраивание логики в shouldDispenseGas, вы сразу понимаете условия, при которых цикл будет продолжаться, и заканчиваться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top