Exit the while loop containing the switch statement

I find it difficult to figure out how to exit a loop containing a switch statement. The gap exits the switch, not the cycle.

Perhaps this is a more elegant solution. I implemented a flag that starts as true and gets false and ends the loop. Can you suggest a better solution?

Background: This code is used in the bar code workflow system. We have handheld computers with built-in barcode scanners. This code is used in one of these functions. It asks the user for different data during the procedure. This part allows them to scroll through some inventory records displaying this information on the PocketPC terminal (paged results) and allows them to enter โ€œDโ€ for โ€œFinishโ€, โ€œQโ€ to exit.

Here is the current C # example that needs to be improved:

do { switch (MLTWatcherTCPIP.Get().ToUpper()) { case "": //scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "P": //scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "D": //DONE (exit out of this Do Loop) // break; // this breaks out of the switch, not the loop // return; // this exists entire method; not what I'm after keepOnLooping = false; break; case "Q": //QUIT (exit out to main menu) return; default: break; } } while (keepOnLooping); 

Here is sample code that does this in VB.NET

 Do Select Case MLTWatcherTCPIP.Get().ToUpper Case "" ''#scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown() Case "P" ''#scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp() Case "D" ''#DONE (exit out of this Do Loop) Exit Do Case "Q" ''#QUIT (exit out to main menu) Return End Select Loop 

Thank,

+38
c # while-loop break
Dec 31 '09 at 10:50
source share
15 answers

I believe this form is becoming more readable:

 bool done = false; while (!done) { switch (MLTWatcherTCPIP.Get().ToUpper()) { case "": //scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "P": //scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "D": //DONE (exit out of this Do Loop) done = true; break; case "Q": //QUIT (exit out to main menu) return; default: break; } } 
+33
Dec 31 '09 at 23:22
source share

I would try to avoid this, but you could use ...

goto

However, angry pitchfork mobs become a professional hazard if you decide to do so.

+40
Dec 31 '09 at 22:56
source share

One option is to reorganize this loop into a method (the "extract" method) and use return .

+28
Dec 31 '09 at 22:58
source share

The only other way I know about is the scary goto. MSDN also talks about this.

However, I see no reason why you would use it in this case. The way you implemented it works great, and is more convenient than goto. I would keep what you have.

+12
Dec 31 '09 at 22:56
source share

You should use the goto statement for layered breaks. This seems to be the only "clean" way in C #. Using the flag is also useful, but requires additional code if the loop has other difficulties at startup.

http://msdn.microsoft.com/en-us/library/aa664756(VS.71).aspx

It is interesting to note that some other non-c languages โ€‹โ€‹have gaps at different levels, making break levels; (Java is just as useless, though, since it uses goto, disguised as a continuation ..: P)

+10
Dec 31 '09 at 22:55
source share

Why not include the switch in a method that returns a boolean to continue the loop? It would be helpful to get the code more readable. There's a reason someone wrote an article that says we don't need goto instructions in the end;)

 do { bool keepOnLooping = TryToKeepLooping(); } while (keepOnLooping); private bool TryToKeepLooping() { switch (MLTWatcherTCPIP.Get().ToUpper()) { case "": //scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "P": //scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "D": //DONE (exit out of this Do Loop) // break; // this breaks out of the switch, not the loop // return; // this exists entire method; not what I'm after return false; case "Q": //QUIT (exit out to main menu) return true; default: break; } return true; } 
+8
Dec 31 '09 at 23:12
source share

Flag is the standard way to do this. The only other way I know is to use goto .

+4
Dec 31 '09 at 22:55
source share

You cannot easily exit the outer loop, but you can continue it.

If you change your logic, you will get this. Note that after the switch operation completes, the break statement must exit the loop.

This is not very readable code, in my opinion, and I think the flag is still the best.

  do { switch (Console.ReadKey().KeyChar.ToString()) { case "U": Console.WriteLine("Scrolling up"); continue; case "J": Console.WriteLine("Scrolling down"); continue; case "D": //DONE (exit out of this Do Loop) break; case "Q": //QUIT (exit out to main menu) return; default: Console.WriteLine("Continuing"); continue; } break; } while (true); Console.WriteLine("Exited"); 
+4
Aug 01 2018-12-12T00:
source share

You can replace the switch statement with the if/else . There is no goto , and the break statement leaves a loop:

 do { String c = MLTWatcherTCPIP.Get().ToUpper(); if (c = "") MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); else if (c = "P") MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp(); else if (c = "D") break; else if (c = "Q") return; else { // Handle bad input here. } } while (keepLooping) 
+2
Dec 31 '09 at 23:13
source share

IMO, this seems like a great way to exit the while . It does what you expect without side effects. I could think of doing

 if(!keepOnLooping) break; 

But this is not entirely different in terms of execution.

+1
Dec 31 '09 at 22:57
source share

Insert it into the function and use the return statement to exit. How about this?

+1
Dec 31 '09 at 23:07
source share

Write something like:

 case "Exit/Break" : //Task to do if(true) break; 

This gap will not be associated with any case. It will belong to the while .

+1
Oct 10 '13 at 6:08 on
source share

You can change the switch statement in a for / foreach loop. After the condition is satisfied, set "keepOnLooping" to false, and then use break to exit the loop. The rest should take care of itself.

0
Dec 31 '09 at 23:09
source share

Another (not so big) alternative is to handle the case unambiguously, where you need to "break out of the loop" with if right away and get it out of the switch block. Not very elegant if the switch is very long:

 do { var expression = MLTWatcherTCPIP.Get().ToUpper(); if (expression = "D") //DONE (exit out of this Do Loop) { statement; break; } switch (expression) { case "": //scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "P": //scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "Q": //QUIT (exit out to main menu) return; default: break; } } while (true); //or whatever your condition is 

You can also make case part of the while condition, assuming that you need to exit the loop, and evaluating the expression itself is trivial (e.g. reading a variable).

 do { switch (expression) { case "": //scroll/display next inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "P": //scroll/display previous inventory location MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); break; case "Q": //QUIT (exit out to main menu) return; default: break; } } while (condition && expression != "D"); 



Also, if for some reason refactoring the whole thing into a new method (which is the most elegant solution for this) is unacceptable, then you can also rely on an anonymous delegate to do the same inside the existing method.

0
Oct. 15 '13 at 8:14
source share

It may or may not work, but lamda, why not give it a shot just for fun.

 while( (expr) => (){ switch(expr){ case 1: dosomething; return true; case 2 : something;return true; case exitloop:return false;} }); 
-one
Aug 23 '17 at 21:53 on
source share



All Articles