Thread: while loop won't break;

  1. #1
    Registered User
    Join Date
    Feb 2012
    Location
    Gunnison, Colorado, United States
    Posts
    10

    while loop won't break;

    So here's what I've got.

    Code:
    //: C03:Menu.cpp// Simple menu program demonstrating
    // the use of "break" and "continue"
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
      char c; // To hold response
      while(true)
      {
        cout << "MAIN MENU:" << endl;
        cout << "l: left, r: right, q: quit -> ";
        cin >> c;
        switch (c)
        {
            case 'q': break;
            case 'l':
            {
                cout << "LEFT MENU:" << endl;
                cout << "select a or b: ";
                cin >> c;
                switch (c);
                {
                    case 'a':
                    {
                        cout << "You chose 'a'" << endl;
                        continue;
                    }
                    case 'b':
                    {
                        cout << "You chose 'b'" << endl;
                        continue;
                    }
                    default:
                    {
                        cout << "You didn't choose a or b!" << endl;
                        continue;
                    }
                }
            }
            case 'r':
            {
                cout << "RIGHT MENU:" << endl;
                cout << "select c or d: ";
                cin >> c;
                switch (c)
                {
                    case 'c':
                    {
                        cout << "You chose 'c'" << endl;
                        continue;
                    }
                    case 'd':
                    {
                        cout << "You chose 'd'" << endl;
                        continue;
                    }
                    default:
                    {
                        cout << "You didn't choose c or d!" << endl;
                        continue;
                    }
                }
            }
        cout << "you must type l or r or q!" << endl;
        }
      }
      cout << "quitting menu..." << endl;
    }
    Now, all the other options work, but the 'q' option will not break the while loop. Can you guys see what I'm doing wrong? I have a feeling it's something little I'm missing.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    The break in case 'q' will only break out of the switch statement, not the encompassing while loop. This is one of the few cases where it is a good idea to use a goto. Your only other choice is a flag, which just makes the code more complicated.
    Code:
    int main()
    {
      char c; // To hold response
      while(true)
      {
        cout << "MAIN MENU:" << endl;
        cout << "l: left, r: right, q: quit -> ";
        cin >> c;
        switch (c)
        {
            case 'q': goto break_while;
            case 'l':
            {
                // ...
            }
            case 'r':
            {
                // ...
            }
        cout << "you must type l or r or q!" << endl;
        }
      }
    break_while:
      cout << "quitting menu..." << endl;
    }

  3. #3
    Registered User
    Join Date
    Feb 2012
    Location
    Gunnison, Colorado, United States
    Posts
    10
    Thanks. I was afraid of that. They really do have a potential for messy programming.

  4. #4
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by oogabooga View Post
    Your only other choice is a flag, which just makes the code more complicated.
    There is another choice, which I think is good design, is to control the while loop with a boolean variable instead of just a true.
    That way, you can set it to false when something deserving a break, happens ; without involving (explicit) flags.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Dagda View Post
    Thanks. I was afraid of that. They really do have a potential for messy programming.
    Don't be scared! This goto is being used in a structured way, breaking to the end of a block, not to some arbitrary point (which results in "spaghetti code"). This is a very common usage and, IMO, far better than a boolean control variable, which adds another variable that you need to set and test when you could simply do what you actually want and jump to the end of the while block with a goto.

    Some languages have a named break construct, where you could give a name to the while statement and then say "break whatever;" to break out of that named block. The goto used in the example I gave simulates that exactly.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The problem is mostly due to nesting too much crap inside each other. Pull the switch statement out into its own function. Make that function return a boolean indicating whether the loop should continue or not. goto is a terrible solution.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How about
    Code:
    int main()
    {
      char c; // To hold response
      bool done = false;
      while( ! done )
      {
        cout << "MAIN MENU:" << endl;
        cout << "l: left, r: right, q: quit -> ";
        cin >> c;
        switch (c)
        {
            case 'q': done = true ; break;
            case 'l':
            {
                // ...
            }
            case 'r':
            {
                // ...
            }
        cout << "you must type l or r or q!" << endl;
        }
      }
      cout << "quitting menu..." << endl;
    }
    or
    Code:
    int main()
    {
      char c; // To hold response
      while( true )
      {
        cout << "MAIN MENU:" << endl;
        cout << "l: left, r: right, q: quit -> ";
        cin >> c;
        if ( c == 'q' ) break;
        switch (c)
        {
            case 'l':
            {
                // ...
            }
            case 'r':
            {
                // ...
            }
        cout << "you must type l or r or q!" << endl;
        }
      }
      cout << "quitting menu..." << endl;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Feb 2012
    Location
    Gunnison, Colorado, United States
    Posts
    10
    Honestly, I just went with the goto. While it can lead to messy coding, when it isn't a copout it seems to me it can be helpful. I don't intend to use it often, but explicitly avoiding it may be a bad habit I don't want to get into. IMO, so far, adding another variable is a bit messier than a single goto in the code, as much as any good programmer is taught to avoid the monstrosity.
    Edit: Though I really do like the individual functions solution. I will use that next time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Best way to break out of loop
    By Ducky in forum C++ Programming
    Replies: 31
    Last Post: 09-07-2010, 11:22 PM
  2. break from for loop
    By taurus in forum C Programming
    Replies: 3
    Last Post: 09-24-2009, 03:54 PM
  3. how could I break this loop?
    By Trafalgar Law in forum C Programming
    Replies: 4
    Last Post: 09-27-2008, 05:11 AM
  4. Loop will not break.
    By silhoutte75 in forum C Programming
    Replies: 1
    Last Post: 03-20-2008, 06:51 PM
  5. Need help with break in do while loop
    By JoelearningC in forum C Programming
    Replies: 3
    Last Post: 03-19-2008, 11:12 PM