Усовершенствованный оператор переключения в цикле с условием продолжения?

Я только что запустил C++, но имейте некоторые предварительные знания на другие языки (vb некоторое время назад, к сожалению), но имейте нечетное затруднительное положение. Я не любил использовать столько операторов IF и хотел использовать переключатель/случаи, поскольку это казалось инструментом для очистки, и я хотел войти в практику.. Но..

Позволяет говорят, что у меня есть следующий сценарий (theorietical код):

while(1) {

  //Loop can be conditional or 1, I use it alot, for example in my game
  char something;
  std::cout << "Enter something\n -->";
  std::cin  >> something;

  //Switch to read "something"
  switch(something) {
    case 'a':
      cout << "You entered A, which is correct";
      break;
    case 'b':
      cout << "...";
      break;
  }
}

И это - моя проблема. Позволяет говорят, что я хотел выйти из Цикла с условием продолжения, будет требоваться два оператора завершения?

Это, очевидно, выглядит неправильным:

case 'a':
  cout << "You entered A, which is correct";
  break;
  break;

Так могу я только делать оператор IF на для использования повреждения;? я пропускаю что-то действительно простое?

Это решило бы много моих проблем, которые я имею прямо сейчас.

8
задан Nullw0rm 20 August 2010 в 19:16
поделиться

9 ответов

Вы можете просто выполнить цикл while для проверки значения типа bool, установленного в одном из ваших операторов case.

bool done = false;    
while(!done)
{
 char something;
  std::cout << "Enter something\n -->";
  std::cin  >> something;

  //Switch to read "something"
  switch(something) {
    case 'a':
      cout << "You entered A, which is correct";
      done = true; // exit condition here
      break;
    case 'b':
      cout << "...";
      break;
  }
}
13
ответ дан 5 December 2019 в 04:30
поделиться

Два оператора break не выведут вас из цикла while. Первый break только выводит вас из оператора switch , а второй никогда не достигается.

Что вам нужно, так это сделать условие цикла while ложным, предполагая, что после оператора switch в цикле ничего нет. Если после переключателя стоит другой код, вам следует проверить состояние после переключателя и перерыва там.


bool done = false;

while(! done)
{
  // do stuff
  switch(something)
  {
    case 'a':
    done = true;  // exit the loop 
    break;
  }

  //  do this if you have other code besides the switch
  if(done)
   break;  // gets you out of the while loop

  // do whatever needs to be done after the switch

}

5
ответ дан 5 December 2019 в 04:30
поделиться

Вы также можете инкапсулировать цикл в функцию и вызвать return внутри case, для случая, когда флага, разрывающего while, недостаточно. Это не очень хорошая практика программирования для некоторых людей, но если вы сохраните функцию простой, я не вижу причин, почему бы и нет.

1
ответ дан 5 December 2019 в 04:30
поделиться

Вы можете изменить свой переключатель на ifsystem . В любом случае он будет скомпилирован в одно и то же.

0
ответ дан 5 December 2019 в 04:30
поделиться

Вы можете заменить коммутатор немного перестроенным ОО-решением ...

#include <iostream>
#include <map>
#include <set>

class input_responder
{
    std::set<char> correct_inputs;
    std::map<char, const char*> wrong_inputs;

public:

    input_responder()
    {
        correct_inputs.insert('a');
        wrong_inputs['b'] = "...";
    }

    bool respond(char input) const
    {
        if (correct_inputs.find(input) != correct_inputs.end())
        {
            std::cout << "You entered " << input << ", which is correct\n";
            return true;
        }
        else
        {
            std::map<char, const char*>::const_iterator it = wrong_inputs.find(input);
            if (it != wrong_inputs.end())
            {
                std::cout << it->second << '\n';
            }
            else
            {
                std::cout << "You entered " << input << ", which is wrong\n";
            }
            return false;
        }
    }
};

int main()
{
    const input_responder responder;
    char input;
    do
    {
        std::cout << "Enter something\n -->";
        std::cin  >> input;
    } while (responder.respond(input) == false);
}
0
ответ дан 5 December 2019 в 04:30
поделиться

Я бы рефакторизовал проверку в другую функцию.

bool is_correct_answer(char input)
{
    switch(input)
    {
    case 'a':
        cout << "You entered A, which is correct";
        return true;
    case 'b':
        cout << "...";
        return false;
    }
    return false;
}

int main()
{
    char input;
    do
    {
        std::cout << "Enter something\n -->";
        std::cin  >> input;
    } while (!is_correct_answer(input));
}
32
ответ дан 5 December 2019 в 04:30
поделиться

Да, в C и C++ нет способа сказать "выйти из нескольких разрушаемых блоков" (где "разрушаемый блок" - это любой цикл или переключатель). Обходные пути включают gotoы и использование булевых переменных для записи того, должен ли внешний "разрушаемый блок" также разрушаться (ни то, ни другое не является элегантным, но такова жизнь).

5
ответ дан 5 December 2019 в 04:30
поделиться

Вы можете попробовать:

  • Использование флагов
  • Использование Goto
  • Использование блока Inner Breakable в функции
  • Использование исключений
  • Использование longjump и setjmp

Тема, очень похожая на этот вопрос

http://www.gamedev.net/community/forums/topic.asp?topic_id=385116

3
ответ дан 5 December 2019 в 04:30
поделиться

Возможно, вас заинтересует идиома именованных циклов в C ++.

#define named(blockname) goto blockname; \
                         blockname##_skip: if (0) \
                         blockname:

#define break(blockname) goto blockname##_skip;

named(outer)
while(1) {

  //Loop can be conditional or 1, I use it alot, for example in my game
  char something;
  std::cout << "Enter something\n -->";
  std::cin  >> something;

  //Switch to read "something"
  switch(something) {
    case 'a':
      cout << "You entered A, which is correct";
      break(outer);
    case 'b':
      cout << "...";
      break(outer);
  }
}
1
ответ дан 5 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: