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!
Related
I was thinking, is there any way you can use throw/try/catch without closing the program?
For example:
function
{
restore point:
//code goes here
try "something";
goto restore point;
}
Is there any method to call function and, if the condition is not verified in try statement, to go back to identifier?
Here`s my case:
int Automat::Retragere()
{
int suma;
cout<<"\n Introduceti suma pe care doriti s-o retrageti: ";
cin>>suma;
if(suma > 5000){
throw "\n Suma este mai mare decat plafonul maximal zilnic.";
}
else{
if(suma > sold){
throw "\n Suma este mai mare decat SOLDUL curent.";
}
else{
cout<<"Operatiune efectuata cu succes.";
sold = sold - suma;
return 1;
}
}
}
marcaj2:
//code here
switch(optiune){
case 1:
Retragere();
goto marcaj2;
case 2:
Depunere();
goto marcaj2;
case 3:
Transfer();
goto marcaj2;
default:
break;
}
I`m asking if, after calling "Retragere" function, is there a posibility to go back to my identifier in case try encounters an error.
In the case you present, Automat::Retragere should probably not throw any exceptions but just return error codes describing what was wrong, since "input too large" (larger than allowed or larger than sum on account) are not really exceptional states. Use an enum with speaking names for that instead of plain int. With a simple return value you are free to use ordinary control flow like a while loop for the input until the number is allowed etc.
Design interlude: That would be different if this was a routine expecting sanitized input so that these conditions indicate a program error. In fact, one should probably already at this stage separate data acquisition from business logic.
This means here that one function is responsible for obtaining the input and checking it; another function would expect valid input (no strings, but a number indicating a valid amount) and perform the actual business action like withdrawel or deposit. It's only a one-liner here but in the real world may involve establishing a connection of some sort, authentication etc.
The business function could throw when presented with an invalid number, because the data provider broke its contract.
Concerning the technical aspect of your question: The 2011 standard says in 15/3:
A goto, break, return, or continue statement can be used to transfer
control out of a try block or handler.
I cannot imagine any ordinary reason to do that, but it is not illegal. (Some of the provisions surrounding goto, arguably even goto proper, target machine generated code or similar scenarios.)
It may well be possible to handle certain exceptions locally; a saner approach (saner than goto directly from inside the catch block to somewhere in the function) would be to have the try/catch block in a loop. The catch block would examine the exception and either set an error code which is then checked in the loop condition, or possibly re-throw exceptions which are unknown or too severe to recover from locally.
Is this what you are looking for?
bool done = false;
while (!done)
{
//marcaj2:
switch(optiune){
case 1:
Retragere();
break; // break out of the switch, i.e. will continue at while (!done)
// so it similar to goto marcaj2
case 2:
Depunere();
break;
case 3:
Transfer();
break;
default:
done = true; // end the while loop
break;
}
}
Others have already commented that the exception throw is bad.
But if you really want it, I think you can do it something like:
bool done = false;
while (!done)
{
try
{
//marcaj2:
switch(optiune){
case 1:
Retragere();
break; // break out of the switch, i.e. will continue at while (!done)
// so it similar to goto marcaj2
case 2:
Depunere();
break;
case 3:
Transfer();
break;
default:
done = true; // end the while loop
break;
}
}
catch (...)
{
// error handling...
}
}
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.
How to execute all cases in switch statement without duplicating existing in big "all-in-one" case ?
For e.g.
switch(obj.nObjType)
{
case eElephant:
...
break;
case eFoo:
...
break;
case eSeptember:
...
break;
default:
return;
}
I want force executing code for all 3 cases (eElephant, eFoo, eSeptember) like there is no break;, for example in case of nObjType = eAllTypes .
You can't just ignore a break. Rather, restructure your code.
switch(obj.nObjType) {
case eElephant:
pokeElephant();
break;
case eFoo:
barTheFoo();
break;
case eSeptember:
rememberSeptember();
break;
case eAllTypes:
pokeElephant();
barTheFoo();
rememberSeptember();
break;
default:
return;
}
Then use if statements:
if (obj.nObjType == eElephant || obj.nObjType == eAllTypes)
{
// Elephant code
}
if (obj.nObjType == eFoo || obj.nObjType == eAllTypes)
{
// Foo code
}
// etc.
This answer is how it should be done.
However:
I can see, it's hard to find as right solution without generating lots
of code lines. Thanks #TobiMcNamobi, but in my switch there is about
200 of cases, so creating a function for each case is not a good idea.
I think, the best can be (unfortunately) duplicating all cases in a
big one. Because, I suppose, if else is much less efficient then
switch statement ?
With this many cases (what on earth are you working on?) even extracting methods leaves you with 200 extra function calls in the body of your switch statement. This could get harder to maintain quickly.
In this case, I would do the following:
switch(enum_variable)
{
case e_all:
case e_1:
e_1_function();
if(enum_variable != e_all){break;} //**
case e_2:
e_2_function();
if(enum_variable != e_all){break;} //**
//...
default:
break;
}
The lines marked //** will break when not doing all cases. It is quick to implement (can be done with a search and replace of break; which speeds things up for you) and does what you want.
With that said, it's still a pretty terrible way of doing it, but exceptions do sometimes have to be made.
I do however recommend that you do not turn to this as a style to use in the future. You may find that you can do better by re-thinking the workflow of your project, as this will probably allow you to simplify and improve. Of course, we don't know what you are working on, so I can't offer more advice.
If you put your switch statement in a function, and make your obj have a list of flags rather than a flag, you can call the function with the switch statement for each flag in the list. Pseudo:
void dostuff(flag)
switch(flag) {
// ...
}
}
for (auto flag in obj.flags) {
dostuff(flag)
}
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;
}
}
Is the following possible in C++?
switch (value) {
case 0:
// code statements
break;
case 1:
case 2:
// code statements for case 1 and case 2
/**insert statement other than break here
that makes the switch statement continue
evaluating case statements rather than
exit the switch**/
case 2:
// code statements specific for case 2
break;
}
I want to know if there is a way to make the switch statement continue evaluating the rest of the cases even after it has hit a matching case. (such as a continue statement in other languages)
How about a simple if?
switch (value)
{
case 0:
// ...
break;
case 1:
case 2:
// common code
if (value == 2)
{
// code specific to "2"
}
break;
case 3:
// ...
}
Once the case label is decided, there is no way to have the switch continue to search for other matching labels. You can continue to process the code for the following label(s) but this doesn't distinguish between the different reasons why a case label was reached. So, no, there is no way to coninue the selection. In fact, duplicate case labels are prohibited in C++.
Yep, just don't put in a break. It will naturally fall down to the other switch statements.