Расширенный оператор switch в цикл while?
Я только что начал C++, но имею некоторые предварительные знания других языков (VB некоторое время назад, к сожалению), но имею странное затруднительное положение. Я не любил использовать так много операторов IF и хотел использовать switch / cases, поскольку это казалось более чистым, и я хотел получить практику.. Но..
допустим, у меня есть следующий сценарий (теоретический код):
while(1) {
//Loop can be conditional or 1, I use it alot, for example in my game
char something;
std::cout << "Enter somethingn -->";
std::cin >> something;
//Switch to read "something"
switch(something) {
case 'a':
cout << "You entered A, which is correct";
break;
case 'b':
cout << "...";
break;
}
}
и это моя проблема. Допустим, я хотел выйти из цикла WHILE, для этого потребовалось бы два перерыва заявления?
Это, очевидно, выглядит не так:
case 'a':
cout << "You entered A, which is correct";
break;
break;
поэтому я могу сделать только оператор IF на "a", чтобы использовать break;? Я упускаю что-то очень простое?
это решило бы многие мои проблемы, которые у меня есть прямо сейчас.
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;
}
}
Я бы рефакторинг проверить другую функцию.
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));
}
да, C и C++ не имеют возможности сказать " выход из нескольких разрушаемых блоков "(где" разрушаемый блок " - это любой цикл или переключатель). Пути включают goto
s и использование булевых переменных для записи того, должен ли внешний" ломаемый блок " также сломаться (ни элегантный, но, это жизнь).
два break
операторы не выведут вас из цикла while. Первый break
только получает вас из switch
заявление и второй никогда не достигается.
что вам нужно, это сделать условие цикла while ложным, предполагая, что в цикле после switch
заявление. Если после коммутатора есть другой код, вы должны проверить условие после switch
и break
там.
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
}
вы можете попробовать:
- Используя Флаги
- Использование Goto
- наличие внутреннего разрушаемого блока в функцию
- Использование Исключений
- использование longjump и setjmp
тема очень похожа на этот вопрос
http://www.gamedev.net/community/forums/topic.asp?topic_id=385116
вы также можете инкапсулировать цикл в функцию и вызвать return внутри корпуса, для случая, когда флаг, нарушающий время, недостаточно. Это не очень хорошая практика программирования для некоторых людей, но если вы держите функцию простой я не понимаю, почему нет.
вас может заинтересовать именем loop идиома В 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);
}
}
вы смогли заменить переключатель с немножко сверх-проектированным решением ОО...
#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);
}
вы можете изменить свой коммутатор на ifsystem. В любом случае, он будет скомпилирован в одно и то же.