有没有办法让 C++ Switch 语句循环回到第一种情况?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17182944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any way to make a C++ Switch Statement loop back to the first case?
提问by DreamBliss
OK, here is a simple code example:
好的,这是一个简单的代码示例:
char answer;
cin >> answer;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
break;
default :
cout << "\nThat was an invalid response.";
}
Obviously I could pull my hair out with a while(answer != 'Y' || answer !=...) But is there a more elegant way of simply returning to the first case after executing the default case? So if a user enters the wrong letter, I simply ask them the question again until they type an acceptable response?
显然我可以花点时间把我的头发拉出来(answer != 'Y' || answer !=...) 但是有没有更优雅的方法在执行默认情况后简单地返回到第一个情况?因此,如果用户输入错误的字母,我只需再次向他们提问,直到他们输入可接受的回复?
No this isn't homework or anything. I'm working through Dawson's C++ Game Programming book, and I wanted to jazz up the program example a little by allowing the user to keep or trade an item. I got all that working beautifully, but if a wrong response is entered it just shows the contents of the inventory and exits. I wanted to get that right. Force the user to enter a correct response, then show the updated inventory afterwards.
不,这不是家庭作业或任何东西。我正在阅读 Dawson 的 C++ Game Programming 一书,我想通过允许用户保留或交易项目来使程序示例更加生动。我让所有这些工作得很好,但是如果输入了错误的响应,它只会显示库存的内容并退出。我想做到这一点。强制用户输入正确的响应,然后显示更新的库存。
Appreciate the help!
感谢帮助!
UPDATE!You have all given me so many different approaches to this - I really appreciate it! I admit I probably did not design this switch statement correctly and I apologize for the contradiction. I will try each of your suggestions and post back here, choosing one as answer. Thank you!
更新!你们都给了我很多不同的方法 - 我真的很感激!我承认我可能没有正确设计这个 switch 语句,我为这个矛盾道歉。我会尝试你的每一个建议,然后在这里发回,选择一个作为答案。谢谢!
OK, I have just gone through all of your answers, trying most of them with my code. I have chosen the simplest, most elegant solution as the answer to my question. But you all have helped me to see different ways of looking at this, and I understand so much more about switch statements now. Using it in fact in place of a while loop in a tutorial I am following right now at YouTube by user What's A Creel?
好的,我刚刚看完了您的所有答案,并使用我的代码尝试了其中的大部分。我选择了最简单、最优雅的解决方案作为我问题的答案。但是你们都帮助我看到了看待这个问题的不同方式,我现在对 switch 语句有了更多的了解。实际上在我现在在 YouTube 上由用户 What's A Creel 关注的教程中使用它代替 while 循环。
I really appreciate all your help! I feel that I have really accomplished a lot in my programming practice today. You guys (and gals) are all awesome!
我真的很感谢你的帮助!感觉今天在我的编程实践中真的收获了很多。你们(和女孩)都很棒!
UPDATED AND COMPLETE CODE:
更新和完整的代码:
#include <iostream>
#include <string>
using namespace std;
// This program displays a hero's inventory
int main()
{
const int MAX_ITEMS = 4;
string inventory[MAX_ITEMS];
int numItems = 0;
inventory[numItems++] = "Rusty Battle Axe";
inventory[numItems++] = "Leather Armor";
inventory[numItems++] = "Wooden Shield";
cout << "Inventory:\n";
for(int i = 0; i < numItems; ++i)
{
cout << inventory[i] << endl;
}
cout << "\nYou open a chest and find a Lesser Healing Potion.";
inventory[numItems++] = "Lesser Healing Potion";
cout << "\nInventory\n";
for(int i = 0; i < numItems; ++i)
{
cout << inventory[i] << endl;
}
cout << "\nYou also find a Short Sword.";
if(numItems < MAX_ITEMS)
{
inventory[numItems++] = "Short Sword";
}
else
{
cout << "\nYou have too many items and can't carry another.";
cout << "\nWould you like to trade the " << inventory[0] << " for the Short Sword? ";
}
while (true)
{
char answer;
cin >> answer;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest." << endl;
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest." << endl;
break;
default:
cout << "\nThat was an invalid response!";
cout << "\nWould you like to trade the " << inventory[0] << " for the Short Sword? ";
continue;
}
break;
}
cout << "\nInventory:\n";
for(int i = 0; i < numItems; ++i)
{
cout << inventory[i] << endl;
}
return 0;
}
回答by AnT
Well, add a loop and it will "loop back" wherever you want.
好吧,添加一个循环,它会在您想要的任何地方“循环回”。
Note that the entire body of switch
is just one long statement with labels in it. It works as any other statement, once you entered it through one of the labels. Just like an ordinary C++ statement will not "loop back" for you by itself unless you make it a cycle or use goto
, neither will the body of switch
"loop back" for you by itself.
请注意,整个正文switch
只是一个带有标签的长语句。一旦您通过其中一个标签输入它,它就可以像任何其他语句一样工作。就像一个普通的 C++ 语句不会为你自己“循环”,除非你把它变成一个循环或使用goto
,switch
“循环”的主体也不会自己为你“循环”。
So, if you want to transfer control back - use the appropriate language construct. You can inject goto
right into the body of that statement and it will work as usual.
因此,如果您想将控制权转回 - 使用适当的语言结构。您可以直接注入goto
该语句的正文,它会照常工作。
switch(answer)
{
case 'y':
case 'Y':
FIRST_OPTION:
...
break;
default :
...;
goto FIRST_OPTION; // Jump to first option
}
You might also want to take a look at Duff's devicefor a more intricate example of control transfer inside switch
statement.
您可能还想查看Duff 的设备,了解更复杂的控制转移内部switch
语句示例。
However, your question seems to contradict itself. You state that you want to ask the user for input again, if the answer was invalid. But the user input is requested and accepted outside of switch
. Why do you say then that you want to return to the first option of switch
???
但是,您的问题似乎自相矛盾。您声明如果答案无效,您想再次要求用户输入。但是用户输入是在switch
. 那你为什么说要回到第一个选项switch
???
回答by paddy
You can use a one-shot loop that breaks at the end and use continue
to jump back to the top:
您可以使用在末尾中断并用于continue
跳回顶部的一次性循环:
while(true)
{
switch(...) {
//...
default:
continue;
}
break;
};
Perhaps a nicer way is to define a set of valid letters, especially if you'll do this kind of thing everywhere in your code:
也许更好的方法是定义一组有效的字母,特别是如果您将在代码中的任何地方执行此类操作:
char GetChoice( const string & prompt, const string & valid_choices )
{
while( cin.good() )
{
cout << prompt << " " << flush;
char c;
if( !cin.get(c) ) break;
size_t pos = valid_choices.find(toupper(c));
if( pos != string::npos ) return valid_choices[pos];
}
return 0; // Error condition.
}
And use like this:
并像这样使用:
switch( GetChoice("Do you want cake?", "YN") )
{
case 'Y':
cout << "Cake for you.\n";
break;
case 'N':
cout << "No cake for you.\n";
break;
case 0:
exit(1); // Error occurred
}
回答by Remy Lebeau
bool valid;
do
{
char answer;
cin >> answer;
switch (answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
valid = true;
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
valid = true;
break;
default :
cout << "\nThat was an invalid response.";
valid = false;
break;
}
}
while (!valid);
回答by Saksham
Use a goto statement in the default section to go back to the input part
在默认部分使用 goto 语句返回输入部分
回答by Vaughn Cato
Here is one approach:
这是一种方法:
bool done = false;
while (!done) {
char answer;
cin >> answer;
done = true;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
break;
default :
cout << "\nThat was an invalid response.";
done = false;
}
}
回答by Rohit Vipin Mathews
Use a while
or do while
loop.
使用while
ordo while
循环。
Eg:
例如:
char answer;
bool loopback = true;
do
{
cin >> answer;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
loopback = false;
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
loopback = false;
break;
default :
cout << "\nThat was an invalid response.";
loopback = true;
}
}
while (loopback);
回答by Abhineet
You can use label
and goto
statement. Label the statement where you are asking the user to input and add a goto
statement in default
case.
Ex::
您可以使用label
和goto
声明。标记您要求用户输入的goto
语句并添加语句default
以防万一。前任::
AskQuestion:
cout << "Press 'Y' for Short Sword Or 'N' for Rusty Battle Axe" << endl;
char answer;
cin >> answer;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
break;
default :
cout << "\nThat was an invalid response.";
goto AskQuestion ;
}
Alternative way is to use do-while
loop with condition while(answer != 'Y' || answer !=...)
as you have already commented in the question. Ex::
另一种方法是使用do-while
带有条件的循环,while(answer != 'Y' || answer !=...)
因为您已经在问题中发表了评论。前任::
do{
cout << "Press 'Y' for Short Sword Or 'N' for Rusty Battle Axe" << endl;
char answer;
cin >> answer;
switch(answer)
{
case 'y':
case 'Y':
inventory[0] = "Short Sword";
cout << "\nYou place the Rusty Battle Axe in the chest.";
break;
case 'n':
case 'N':
inventory[0] = "Rusty Battle Axe";
cout << "\nYou leave the Short Sword in the chest.";
break;
default :
cout << "\nThat was an invalid response.";
}
}while( answer != 'Y' || answer != 'y' || answer != 'N' || answer != 'n' ) ;