sccs
sccs

Reputation: 1163

Exiting while loop after x number of loops

I have 2 layers of maps, the second of which points to a queue. I would like to extract a certain number of items from the queue (and hence the maps), but I seem to have problems inserting a break/return/exit (I'm not sure which to use in this case) in the right place.

This is the code:

#include <iostream>
#include <queue>
#include <map>

using namespace std;

int main()
{
    typedef std::queue<int> MessageQueue;
    typedef std::map<int, MessageQueue> PriorityMap;
    typedef std::map<int, PriorityMap> ClientMap;

    ClientMap clients;

    int priorities = 7;

    clients[10][1].push(1);
    clients[10][1].push(2);
    clients[10][5].push(3);
    clients[10][7].push(3);

    for (int j = 1; j<3; j++) //this determines how many times an element will be 'popped' from a queue
    {
        while (!clients[10].empty())
        {
            for (int i = priorities; i > 0; i--)
            {
                while (clients[10].find(i) != clients[10].end())
                {
                    cout << "priority " << i << endl;
                    cout << clients[10][i].front() << endl;
                    clients[10][i].pop();

                    if (clients[10][i].empty())
                        clients[10].erase(i);

                }

            }

            break; //I don't know where this should go in order for the while loop to stop executing after an element has been popped
        }

    }

    return 0;
}

with this result

priority 7
3
priority 5
3
priority 1
1
priority 1
2

but the result I would like instead is

priority 7
3
priority 5
3

Upvotes: 0

Views: 909

Answers (2)

Bernhard Barker
Bernhard Barker

Reputation: 55609

In the context of the main method, exit and return will basically do the same thing. Neither are recommended to do in the middle of a loop.

My recommendation:

bool done = false;
for (...; ... && !done; ...)
{
   while (... && !done)
   {
      ...
      done = true;
      ...
   }
}

Or, in the context of your problem:

int count = 2;
for (int j = 1; j<3 && count > 0; j++)
{
   while (!clients[10].empty() && count > 0)
   {
      for (int i = priorities; i > 0 && count > 0; i--)
      {
         while (clients[10].find(i) != clients[10].end() && count > 0)
         {
            ...
            count--;
            ...
         }
      }
   }
}

I know you can just do && count instead of && count > 0, but the latter is more readable.

Upvotes: 1

Daniel Frey
Daniel Frey

Reputation: 56863

Instead of the outer loop, use a counter and goto:

int countRemoved = 0;
while (!clients[10].empty())
{
    for (int i = priorities; i > 0; i--)
    {
        while (clients[10].find(i) != clients[10].end())
        {
            cout << "priority " << i << endl;
            cout << clients[10][i].front() << endl;
            clients[10][i].pop();
            if (clients[10][i].empty())
               clients[10].erase(i);
            if( ++countRemoved == 2 ) goto stop;
       }
    }
}
stop:

Upvotes: 0

Related Questions