I'm writing some code that looks like this:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break; // **HERE, I want to break out of the loop itself**
}
}
Is there any direct way to do that?
I know I can use a flag, and break from the loop by putting a conditional break just after the switch. I just want to know if C++ has some construct for this already.
You can use goto.
while ( ... ) {
switch( ... ) {
case ...:
goto exit_loop;
}
}
exit_loop: ;
An alternate solution is to use the keyword continue in combination with break, i.e.:
for (;;) {
switch(msg->state) {
case MSGTYPE:
// code
continue; // continue with loop
case DONE:
break;
}
break;
}
Use the continue statement to finish each case label where you want the loop to continue and use the break statement to finish case labels that should terminate the loop.
Of course this solution only works if there is no additional code to execute after the switch statement.
Premise
The following code should be considered bad form, regardless of language or desired functionality:
while( true ) {
}
Supporting Arguments
The while( true ) loop is poor form because it:
Breaks the implied contract of a while loop.
The while loop declaration should explicitly state the only exit condition.
Implies that it loops forever.
Code within the loop must be read to understand the terminating clause.
Loops that repeat forever prevent the user from terminating the program from within the program.
Is inefficient.
There are multiple loop termination conditions, including checking for "true".
Is prone to bugs.
Cannot easily determine where to put code that will always execute for each iteration.
Leads to unnecessarily complex code.
Automatic source code analysis.
To find bugs, program complexity analysis, security checks, or automatically derive any other source code behaviour without code execution, specifying the initial breaking condition(s) allows algorithms to determine useful invariants, thereby improving automatic source code analysis metrics.
Infinite loops.
If everyone always uses while(true) for loops that are not infinite, we lose the ability to concisely communicate when loops actually have no terminating condition. (Arguably, this has already happened, so the point is moot.)
Alternative to "Go To"
The following code is better form:
while( isValidState() ) {
execute();
}
bool isValidState() {
return msg->state != DONE;
}
Advantages
No flag. No goto. No exception. Easy to change. Easy to read. Easy to fix. Additionally the code:
Isolates the knowledge of the loop's workload from the loop itself.
Allows someone maintaining the code to easily extend the functionality.
Allows multiple terminating conditions to be assigned in one place.
Separates the terminating clause from the code to execute.
Is safer for Nuclear Power plants. ;-)
The second point is important. Without knowing how the code works, if someone asked me to make the main loop let other threads (or processes) have some CPU time, two solutions come to mind:
Option #1
Readily insert the pause:
while( isValidState() ) {
execute();
sleep();
}
Option #2
Override execute:
void execute() {
super->execute();
sleep();
}
This code is simpler (thus easier to read) than a loop with an embedded switch. The isValidState method should only determine if the loop should continue. The workhorse of the method should be abstracted into the execute method, which allows subclasses to override the default behaviour (a difficult task using an embedded switch and goto).
Python Example
Contrast the following answer (to a Python question) that was posted on StackOverflow:
Loop forever.
Ask the user to input their choice.
If the user's input is 'restart', continue looping forever.
Otherwise, stop looping forever.
End.
Code
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
Versus:
Initialize the user's choice.
Loop while the user's choice is the word 'restart'.
Ask the user to input their choice.
End.
Code
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
Here, while True results in misleading and overly complex code.
A neatish way to do this would be to put this into a function:
int yourfunc() {
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
return;
}
}
}
Optionally (but 'bad practices'): as already suggested you could use a goto, or throw an exception inside the switch.
AFAIK there is no "double break" or similar construct in C++. The closest would be a goto - which, while it has a bad connotation to its name, exists in the language for a reason - as long as it's used carefully and sparingly, it's a viable option.
You could put your switch into a separate function like this:
bool myswitchfunction()
{
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
return false; // **HERE, I want to break out of the loop itself**
}
return true;
}
while(myswitchfunction())
;
Even if you don't like goto, do not use an exception to exit a loop. The following sample shows how ugly it could be:
try {
while ( ... ) {
switch( ... ) {
case ...:
throw 777; // I'm afraid of goto
}
}
}
catch ( int )
{
}
I would use goto as in this answer. In this case goto will make code more clear then any other option. I hope that this question will be helpful.
But I think that using goto is the only option here because of the string while(true). You should consider refactoring of your loop. I'd suppose the following solution:
bool end_loop = false;
while ( !end_loop ) {
switch( msg->state ) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
end_loop = true; break;
}
}
Or even the following:
while ( msg->state != DONE ) {
switch( msg->state ) {
case MSGTYPE: // ...
break;
// ... more stuff ...
}
There's no C++ construct for breaking out of the loop in this case.
Either use a flag to interrupt the loop or (if appropriate) extract your code into a function and use return.
No, C++ does not have a construct for this, given that the keyword "break" is already reserved for exiting the switch block. Alternatively a do..while() with an exit flag could suffice.
do {
switch(option){
case 1: ..; break;
...
case n: .. ;break;
default: flag = false; break;
}
} while(flag);
You could potentially use goto, but I would prefer to set a flag that stops the loop. Then break out of the switch.
Why not just fix the condition in your while loop, causing the problem to disappear?
while(msg->state != DONE)
{
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
// We can't get here, but for completeness we list it.
break; // **HERE, I want to break out of the loop itself**
}
}
It amazes me how simple this is considering the depth of explanations... Here's all you need...
bool imLoopin = true;
while(imLoopin) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
imLoopin = false;
break;
}
}
LOL!! Really! That's all you need! One extra variable!
I think;
while(msg->state != mExit)
{
switch(msg->state)
{
case MSGTYPE: // ...
break;
case DONE:
// ..
// ..
msg->state =mExit;
break;
}
}
if (msg->state ==mExit)
msg->state =DONE;
I got same problem and solved using a flag.
bool flag = false;
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
flag = true; // **HERE, I want to break out of the loop itself**
}
if(flag) break;
}
Because the switch uses the break to break out from the switch (not from the while(1)), it needs the goto-statement:
while(1) {
switch (*p) {
case ' ':
p++;
break;
case '\n':
p++; *s=p; return(i);
case '\0':
*s=p; return(i);
default:
token[i]=p;
i++;
p++;
goto ex1;
};
};
ex1:
I can't add multiple case to same line like:
case ' ','\t':
it would be
case ' ': case '\t':
That's why maybe the break used here...
It looks the most frequent cases should be placed at the top of the list to make the program run faster.
It may not have parallel execution for searching the different cases.
It is possible that the standard c then has missing some methods about this switching:
https://blog.hackajob.co/better-c-switch-statements-for-a-range-of-values/
=> allows you to use the <, >, <=, and >= operators in a switch expression
I was thinking that it should be (if c-language syntax changed) like:
switch (c) {
case >= 5:
... op1
endcase;
case == 1:
case == 3:
... op2
endcase;
default:
...
};
where op2 is executed when c is equal to 1 or 3 and when c is larger than or equal to 5 op1 is executed.
Because comparison for equal or larger/smaller than would occur easily in similar manner.
while(1) {
switch (c) {
case >= 2:
... op1
case <= 5:
... op2
break;
default:
...
};
};
this case op1 is executed for c larger than 2 and op2 executed for 2<=c<=5 and break exits it from while-loop.
The simplest way to do it is to put a simple IF before you do the SWITCH , and that IF test your condition for exiting the loop .......... as simple as it can be
The break keyword in C++ only terminates the most-nested enclosing iteration or switch statement. Thus, you couldn't break out of the while (true) loop directly within the switch statement; however you could use the following code, which I think is an excellent pattern for this type of problem:
for (; msg->state != DONE; msg = next_message()) {
switch (msg->state) {
case MSGTYPE:
//...
break;
//...
}
}
If you needed to do something when msg->state equals DONE (such as run a cleanup routine), then place that code immediately after the for loop; i.e. if you currently have:
while (true) {
switch (msg->state) {
case MSGTYPE:
//...
break;
//...
case DONE:
do_cleanup();
break;
}
if (msg->state == DONE)
break;
msg = next_message();
}
Then use instead:
for (; msg->state != DONE; msg = next_message()) {
switch (msg->state) {
case MSGTYPE:
//...
break;
//...
}
}
assert(msg->state == DONE);
do_cleanup();
while(MyCondition) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
MyCondition=false; // just add this code and you will be out of loop.
break; // **HERE, you want to break out of the loop itself**
}
}
If I remember C++ syntax well, you can add a label to break statements, just like for goto. So what you want would be easily written:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break outofloop; // **HERE, I want to break out of the loop itself**
}
}
outofloop:
// rest of your code here
while(true)
{
switch(x)
{
case 1:
{
break;
}
break;
case 2:
//some code here
break;
default:
//some code here
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
so in this function of mine, it is spitting out this warning: "carboard.c:79:1: warning: control reaches end of non-void function [-Wreturn-type]". Program runs fine, but i just want it to compile cleanly.
here is the code of the function:
int loadMainMenu()
{
char choice[LINE + EXTRA_SPACES];
Boolean menu = TRUE;
printf("\nWelcome to Car Board\n");
printf("--------------------\n");
printf("1. Play Game\n");
printf("2. Show Student's Information\n");
printf("3. Quit\n");
printf("\n");
printf("Please Enter Your Choice:\n");
do
{
int input;
fgets(choice, LINE + EXTRA_SPACES, stdin);
if (choice[strlen(choice) - 1] != '\n')
{
printf("BUFFER OVERFLOW!\n\n");
readRestOfLine();
}
choice[strlen(choice) - 1] = 0;
input = atoi(choice);
switch(input)
{
case 1: playGame();
break;
case 2: showStudentInformation();
loadMainMenu();
break;
case 3:
printf("Bye bye! \n");
return EXIT_SUCCESS;
break;
default: printf("Invalid input\n");
loadMainMenu();
break;
}
}while(menu);
}
You need to have a return statement in your code. Since your function is returning an integer you must have something likek return x; where x is an integer or you can declare function void.
The compiler is not that smart to figure out the do ... while never terminates.
To fix this, first ensure the loop cannot end by making it guaranted infinite using a constant:
do {
} while ( true );
If that doesn't work, try
while ( true ) {
...
}
The compiler might require a specific pattern ( for ( ; ; ) might also be worth a try; it is also a matter of personal preference).
If that still does not work, just return 0; after the loop above. That might be optimised away, so no extra code at best. At worst, you have to live with some dangling code.
An alternative would be to temporarily disable the warning using a pragma. That should really only be the last ressort.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Here i just experienced with the switch command and if command at C. I have omitted the if command by comment and wrote the same command by using switch command. But its now working as i gave the instruction. Where i have mistaken? As i am a learner please pardon my mistakes..
#include <stdio.h>
#include<stdlib.h>
int main()
{
char card_name[3];
puts("enter the card name: ");
scanf("%2s", card_name);
/*int val=0;
if (card_name[0]=='K') {
val=10;
} else if (card_name[0]=='Q'){
val=10;
} else if (card_name[0]=='J'){
val=10;
} else if (card_name[0]=='A'){
val=11;
}else{
val=atoi(card_name);
}*/
int val=0;
switch (card_name[0]) {
case 'K':
case 'Q':
case 'J':
val=10;
break;
case 'A':
val=11;
default:
val=atoi(card_name);
break;
}
if (val>2 && val<7) {
puts("the count has gone up!");
} else if(val>=10){
puts("The count has gone down");
}
return 0;
}
You're missing another break in the 'A' case. Your switch statement then should look something like this (I added indentation for you).
switch (card_name[0]) {
case 'K':
case 'Q':
case 'J':
val=10;
break;
case 'A':
val=11;
break; // you were missing a break statement here
default:
val=atoi(card_name);
break;
}
There is no break; for case 'A' .. Is that intentional ?
You are missing a break statement in case 'A':,before the default label. You should break after each statement in a case statement unless it was your intent to have the other cases execute, as well as a given case.
while (1)
{
c = getchar();
switch(state)
{
case 0:
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == Bit_SET))
{
state=1;
}
if ( c=='p')
{
state = 2;
}
break;
case 1 :
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) != Bit_SET))
{
state = 0;
}
break;
case 2:
iprintf("%s",led_name_arr[i]);
if (c=='r')
{
state=0;
}
break;
}
}
I want to print the printf and then reach state2 .. how can this be achieved .below is what i have tried and where i am stuck .
psuedocode:
if ( c==P)
{
printf(" hi");
state 2;
}
** in this case the printf statement does not get executed **
or
case 2:
iprintf("%s",led_name_arr[i]);
if (c=='r')
{
state=0;
}
break;
** in this case the printf statement keeps printing in a loop **
i dont want the while loop to stop , in a continuous loop i want case 0 keeps working , but when it get the input p .. it pauses and executes the printf ... and waits till it gets a r to resume case 0 .... Thus the program never halts but waits to either get "P" or "R" to execute each case... I hope i make sense
Any help will be appreciated .
Your breaks are breaking out of the switch ... case not the while. You'll need to use some kind of boolean flag to break out of the outer loop, e.g.:
bool someflag = true;
while(someflag){
switch(something){
case a:
someflag = false; // set the flag so we break out of the loop
break; // break out of the switch-case so we don't enter case b
case b:
// do something else
break;
}
}
-------- EDIT, because I misunderstood the question ------------
I think you need an extra state in your logic, right now (ignoring state 1), you have two states:
Wait for a p, when you get one, goto 2.
printf for each character until you get an r, then goto 1
What you want is:
Wait for a p, when you get one, goto 2.
Do a printf, then goto 3.
Wait for an r, when you get one, goto 1.
i am not sure what you are asking but i m pretty sure what you want in case 2 is something like this:
case 2:
iprintf("%s",led_name_arr[i]);
while(c!='r')
{
c = getchar();
}
state=0;
break;
You've created an infinite loop with the while (1) statement that has no possible exit. The break statements within the switch apply to the switch statement, not the while loop. You need another break statement outside the switch.
well,
initialize state to 0
compile and run the program
first time enter p // here state =2
then enter r // here state = 0
....continue in a loop due to while(1)
Because you are not breaking the while(1) loop. Use one more break for while loop.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Code before the first ‘case’ in a switch-statement
I have the following set of code in C:
void isFindValue(int value1, int value2)
{
switch (value1)
{
case 1:
printf("value1 is found!\n");
break;
case 2:
printf("value1 is found!\n");
break;
case 3:
switch(value2)
{
printf("aaaaaaaaaaaaa\n");
case 6:
printf("bbbbbbbbbbbb\n");
printf("value2 is found!\n");
break;
}
default:
break;
}
if I call the function as is isFindValue(3,6); the printf of bbbbbbbbbbbb show up, but aaaaaaaaaaaaa does not, why this will happen? should we not do something before the case?
Because switch () works using labels. It jumps to the label of which the condition is satisfied. So when reaching
switch(value2) {
printf("aaaaaaaaaaaaa\n");
case 6:
the control flow immediately jumps to the label case 6: so that it skips the call to printf().
The solution would be placing it correctly, outside of the inner switch:
case 3:
printf("aaaaa\n");
switch (value2) {
etc.
"aaaaaaaaaaaaa" is not showing up because it is misplaced (it's not contained in a label so it is unreachable). You need to move it up to before the second switch statement:
case 3:
printf("aaaaaaaaaaaaa\n");
switch(value2)
{
// body
}
The call to the printf function in the statement :
printf("aaaaaaaaaaaaa\n");
cannot be reached because it is before the first case statement of the second switch.
see Code before the first 'case' in a switch-statement
"aaaaaaaaaaaaa\n" is not being printed within any case. Your code is not properly structured.
Try moving the statement out of the switch block like this:
printf("aaaaaaaaaaaaa\n");
switch(value2)
{
case 6:
printf("bbbbbbbbbbbb\n");
printf("value2 is found!\n");
break;
}
break;
switch always look for case and that's why aaaaaaaaaaaa was skipped. It will execute the statement of related case block.