2010-05-07 141 views
8

我刚开始使用C++,但对其他语言有一些先前的知识(不幸),但有一个奇怪的困境。我不喜欢用这么多的IF语句,并想利用交换机/案例,因为它似乎更清洁了,我想在实践中获得。但是..while循环中的高级switch语句?

可以说我有以下情形(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; 
    } 
} 

这就是我的问题。假设我想退出WHILE循环,它需要两个break语句?

显然,这看起来错:

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

所以我只能做一个IF语句的“a”到使用break;?我错过了很简单的事情吗?

这将解决我现在有很多问题。

+3

基于标题,我认为这可能是一个达芙的设备问题。不。有没有一个'boring'标签? – 2010-05-07 05:08:22

+0

很高兴你的问题解决了,这些东西并不是最有趣的。 – 2010-05-09 06:48:42

回答

13

您可以简单地让while循环检查在您的case语句之一中设置的bool值。

+1

我想说这个答案有些不太理想(但没有任何错误)。 如果在switch语句下添加了代码,即使问题是直接退出外部循环,它也会运行。 如果(完成)休息,我会使用Dimas;方法或转到。 – 2010-05-07 07:11:56

+0

是的,这是该解决方案的一个陷阱,代码在该开关下执行。在那里同意。 – Robb 2010-05-07 14:45:32

+0

有趣我总是用(while)(跑步) – kenny 2010-05-07 18:53:57

5

是的,C和C++没有办法说“退出多个易碎块”(其中“易碎块”是任何回路或开关)。解决方法包括goto和使用布尔变量来记录外部“易碎块”是否也应该打破(既不优雅也不过是生活)。

5

两个break语句不会让你离开while循环。第一个break只能让你脱离switch声明,第二个永远不会到达。

你需要的是让while循环的条件为假,假设switch语句后循环中没有任何内容。如果切换后有其他代码,则应检查switchbreak之后的情况。

 

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 

} 
 
+0

为什么不只是做,而(真)如果你要检查是否(完成)。这是多余的。 – 2010-05-07 18:53:35

+0

它取决于...您可能会或可能不想在切换后立即断开。 – Dima 2010-05-07 19:24:35

1

您也可以将循环封装到一个函数中,并在案例中调用返回值,以便标记中断的情况不够。 对于一些人来说这不是一个好的编程习惯,但如果你保持这个功能简单,我不明白为什么不这样做。

0

您可以将您的交换机更改为if系统。无论如何,它将被编译为相同的东西。

+0

好的说法,如果没关系,我不介意稍微太结构化的代码。 :P – Nullw0rm 2010-05-07 05:04:05

+0

请务必添加注释,解释为什么您使用'if/else-if',以便您(或其他人)稍后不会看到它,并将其更改为更明显的开关语句,从而打破一切。没有双关语意。 – 2010-05-07 05:11:41

+0

如果有人重构你的代码,并没有注意到他们已经改变了方法的基本行为,我不确定我会相信他们首先阅读评论。 – 2010-05-07 05:33:25

3

你可以尝试:

  • 使用标志
  • 使用转到
  • 具有内易碎块到功能
  • 使用异常
  • 使用跳远踏板和setjmp

与此问题非常相似的主题

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

+0

标志和包装块功能工作。 Goto坏了。这里的例外情况并不合适。退出循环并不是错误。 – Dima 2010-05-07 05:13:55

+5

Goto还不错。我认为在这种情况下使用goto是合适的,正如标志一样。 – 2010-05-07 05:35:54

+0

在我使用goto的示例代码中,如果在switch语句之后有代码,它将保持整洁。 – mikek3332002 2010-05-07 05:51:15

32

我会重构检查到另一个函数。

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)); 
} 
+0

这实际上很漂亮,值得赞赏。 – Thomas 2010-05-07 06:59:23

+0

这应该是答案。 – 2010-05-07 07:23:26

+0

需要修改其中一个功能,以说明大写或小写选择。 – 2010-05-07 17:06:52

0

你可以用略超工程OO液更换开关...

#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); 
} 
1

您可能会感兴趣在C++ named loop idiom

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