Switch case to break an outer loop? [duplicate] - c++

This question already has answers here:
How to break out of a loop from inside a switch?
(20 answers)
Closed 9 years ago.
This isn't a specific problem that I actually am trying to implement, but it ocurred to me that I do not know how to do this, so I will give a simple example to illustrate:
Suppose we have a while loop containing a switch statement, for instance:
while(some_cond){
switch(some_var){
case 1:
foo();
break;
case 2:
bar();
break;
}
}
what would we do if we wanted to break out of the while loop in case 1, say?
We can't do break; break;, since the second will never happen.
We also can't do break *un*conditionally in the while loop, since this would happen in any case.
Do we have no choice but to if (some_var == 1) break; in the while loop, or else append && !flag) to the while condition, and set flag = 1?

Various options, in approximate order of tastefulness:
Move the loop into a separate function. Use return to stop looping.
Replace while(1) with while(looping) and set to false to stop looping. Use continue if you need to skip the rest of the current iteration.
Use goto to jump past the end of the loop. How bad can it be?
Surround the loop with a try block, and throw something to stop looping.

You can use goto (don't go too wild with goto though).
while ( ... ) {
switch( ... ) {
case ...:
goto exit_loop;
}
}
exit_loop: ;

Have your while use a variable modified within your loop.
bool shoulEnterLoop = true;
while(shoulEnterLoop ){
switch(some_var){
case 1:
if ( !foo() )
shoulEnterLoop = false;
break;
case 2:
bar();
break;
}
}

Related

How Do while inside switch statement works in c

I have a code snippet where a do while statement is inside switch condition of case0, by default the case value is case1 but it seems executing case0. The output of the program print is 6. How is this possible, can someone explain the flow of code here. Thanks in advance for your answers.
int main()
{
int a = 1, t =0,n=2;
switch(a)
{
case 0:
do
{
t++;
case 4:t++;
case 3:t++;
case 2:t++;
case 1:t++;
}while(--n>0);
printf("%d",t);
}
return(0);
}
Since a is 1 in the beginning, case 1 will be executed. Then the loop condition is satisfied, thus it will loop again and execute t++; and all other cases until it tests the loop condition again and breaks the loop.
To get out of the switch, use the break command before every case.
Switch cases are similar to labels for goto.
You start at case 1, which is inside the loop – effectively using that as your starting point – and then execute the loop normally while "falling through" the cases as you go.
Here is the equivalent using goto:
int main()
{
int a = 1, t =0,n=2;
if (a == 0)
goto case_0;
if (a == 1)
goto case_1;
if (a == 2)
goto case_2;
if (a == 3)
goto case_3;
if (a == 4)
goto case_4;
case_0:
do {
t++;
case_4:
t++;
case_3:
t++;
case_2:
t++;
case_1:
t++;
} while (--n > 0);
printf("%d",t);
}
(The actual generated code might use a jump table rather than a series of conditionals, but the behaviour is the same.)
This is known at Duff's device.
case are mostly only label.

How to replace the 'break'?

In my program I have a structure similar to the following one:
while (true) {
int c;
cout << "Type a command: ";
cin >> command;
switch (c) {
case 1:
// [...]
if (!condition) break;
// [...]
if (!condition2) break;
// [...]
if (!condition3) break;
// [...]
break;
case 2:
// [...]
break;
default:
break;
}
}
But our professor told us to never use the break except in the switch case to exit... I was wondering if there's a better and smarter way to replace the block if(!condition) break;.
My main goal is to prevent the program from doing certain actions if condition is not verified.
In order to avoid break you need to use the opposite condition, and instead of breaking the flow, control it:
switch (c) {
case 1:
// [...]
if (condition) {
// [...]
if (condition2) {
// [...]
if (condition3) {
// [...]
} // if the third condition is false, you will continue to the break.
} // if the second condition is false, you will continue to the break.
} // if the first condition is false, you will continue to the break.
break;
// ...
}
EDIT
To avoid complex conditions, you can use functions:
void condition_1_actions();
void condition_2_actions();
void condition_3_actions();
// ... main ...
case 1:
if (condition) condition_1_actions();
break;
// ... After main ...
condition_1_actions() {
// do some actions
// Calculate condition2 or pass it as parameter
if (condition2) condition_2_actions();
}
condition_2_actions() {
// do some actions
// Calculate condition3 or pass it as parameter
if (condition3) condition_3_actions();
}
condition_3_actions() {
// do some actions
}
I'm sure that "your professor" would agree: "if it ain't broke, don't fix it."
The logic as-written is clear, and I presume that it works. Also, as-written it would be maintainable: I wouldn't have to radically change the source-code if when I needed to add a new condition to it. Just leave it alone. Anything that you hear from a professor – or anyone else – is a guideline!
"Clarity" is always key, because as years go by your source-code is going to be added-to by many others. I like the original idiom because each of the cases is clearly distinct: "make this test, and then bail-out." (Could be break or return depending on the situation.) It's very easy to see how the logic goes, and it's equally easy to add another case to it "in the same vein."
In the end – "it makes absolutely no difference to the digital computer." (As Perl programmers like to say, "there's more than one way to do it.™") But it might be attractive to your [future ...] colleagues. There are no absolutes here. Just try to be nice to them. Be "stupid-obvious."

Using a switch in a do..while loop, in C++

A simple programm that reads strings, and responds using a switch;
in this do-while loop containing a switch, I am able to run case 1-4 with no issues, but once i hit the default case, the programme simply loops the default case over and over again the code is as follows;
do { switch ( switchstring (entry, input) )
/*the switchstring function is one 1 wrote to convert a given entry(string),
into an input(integer)*/
{
case 1:
//code
repeat = 2;
break;
case 2:
//code
repeat = 2;
break;
case 3:
//code
repeat = 2;
break;
case 4:
//code
repeat = 2;
break;
default:
//code
repeat = 1;
break;}} while(repeat == 1);
the 2nd question is regarding my switchstring() function; is there a way to change the switch function such that it reads;
case (insert string):
i.e. so that I can remove the entire switchstring() function
thanks in advance!
Show us how switchstring (entry, input) works.
The problem you are facing is because, in default you do the following:
repeat = 1;
Which makes while(repeat == 1) always true. And then switchstring (entry, input) always return something that makes your switch block always go the the default case again.
When no case will be true in switch, then it will go in default case of switch and you are specifying repeat=1; in default. After that while condition will be checked and it will be true because repeat is 1, again it will go to do and check condition, your switch function will return something and it will go to default.
To solve 2nd question regarding your switchstring() function, you have to show your code what you are doing in that function, So that i can give you best suggestion.

While loop in case statement (C++)

Is anyone can help me resolve I think trivial issue for someone who knows C langue quite well.
I have some piece of code however label_start_menu: doesn't work for me.
What I want to achieve is back to default: Now if e.g. 3 == 3 while loop is working infinite and is not possible to return to default:
switch (counter1) {
case 1:
menu_clock();
delay(2000);
while(true){
Serial.println("loop1");
Serial.println("loop1");
Serial.println("loop1");
if(3 == 3)
{
break;
goto label_start_menu;
}
}
break;
case 2:
menu_media();
delay(2000);
break;
default:
label_start_menu:
menu_start();
break;
}
}
Thanks,
ojdas
if(3 == 3)
{
break;
goto label_start_menu;
}
goto will never get executed because the break statement will break out of your loop right there.
My advice would be to get rid of the goto, and to just call menu_start() in the if statement, and then break, instead of using a goto.
I'm not sure what you're trying to do with your while loop, exactly, but you've got your break; statement in front of your goto label_start_menu; statement, so it will never be reached.
More complete answer: there's absolutely no need for the goto in the first place. You're already calling another function. Rewrite the whole thing like this:
switch (counter1)
{
case 1:
menu_clock();
delay(2000);
Serial.println("loop1");
Serial.println("loop1");
Serial.println("loop1");
menu_start();
break;
case 2:
menu_media();
delay(2000);
break;
default:
menu_start();
break;
}
the break should be the last thing..
also, why put it in a loop? that is an infinite loop.. just call it and then break breaking will get you out of the switch and will not continue so make sure you do everything before you break, so put your goto label_start_menu; before the break and remove the if statement and the other break under it.
if you want to loop it then there are other loop methods you can use.. google is great with that!
Im going to repost #40two's answer, because it exactly hits the nail about usage of goto (besides the other flaws coming in the same way (no reasonable loop break conditions)).
#40two: XKCD is a real good source for insight, as lomg you're able to read it!

coldfusion calling another case within a switch

I have a switch like thus (written in cfscript):
switch (something) {
case "stuff":
if(this eq that){
writeDump("hello");
} else { /* do other? */ }
break;
case "other":
//do something else
break;
}
In my else, I want to be able to tell it that I want the "other" case to be invoked. Is this possible? (I seem to remember doing this in other languages.)
There is no GOTO construct in CF, no. And that's pretty much what you're asking for.
If your switch is really as simple as you indicate, and you want to fall through to the NEXT case when the condition is false, what you could do is to have the break statement in the true branch of the if clause, and have no break statement in the false branch. Then when the false branch runs, processing will not exit the case when it's done; it'll fall through to the next case.
As Adam explained, it is possible, here is some code to show how:
something = "stuff";
test = "more stuff";
switch (something) {
case "stuff":
if(test eq "more stuff"){
writeOutput("<p>Something</p>");
break;
}
case "other":
writeOutput("<p>something Else</p>");
break;
}
Change the values of 'something' and 'test' to see different results. When using a switch in cfscript, if there is no 'break' then ColdFusion will continue processing the cases until it hits one.
As far as I'm aware that's not possible. You'll need to use an if else statement, or nested is/else, instead of the switch.
something = "other";
if (something eq "stuff" and 1 eq 2) {
writeDump("hello");
} else if (something eq "other") {
writedump("other");
}