Home > Mobile >  How to display an entire queue struct
How to display an entire queue struct

Time:12-22

I designed a circular queue program which provides queue management system. Everything works fine, except that in some cases, I can't print the queue.

My code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CAPACITY 5
#define MAX_STRING_SIZE 40
#define TRUE 1
#define FALSE 0


struct queue
 {
 char items[CAPACITY][MAX_STRING_SIZE]; 
 int front,rear ;
 };
 
void cqinsert(struct queue * , char name[]);
void cqdelete(struct queue *);
int empty(struct queue *);


int main(void)
{
int order;
char name[MAX_STRING_SIZE]; 
int menu;
    
char operation;
int x;
struct queue q;
q.front = q.rear = CAPACITY - 1;
 


do{
    printf(">>Please enter an operation number from the given list:\n");
    printf("[1]-Customer Entry\n[2]-Customer Exit\n[3]-Waiting Customers List\n[4]-Exit\n");
    scanf("%d",&menu);
    switch(menu) {
        case 1: printf("Enter customer name: ");
                scanf("%s",&name);
                cqinsert(&q,name);
                break;
        
        case 2: cqdelete(&q);
                break;
        
        case 3: if(q.front==CAPACITY-1) {
            
                order = 1;
                    for(int i=0;i<=q.rear;i  ) {    
                        printf("[%d]-%s\n",order,q.items[i]);
                        order  ;
                    }
                break;
                }
                
                else {
                    order=1;
                    for(int i=q.front 1;i<=q.rear;i  ) {
                    
                        printf("[%d]-%s\n",order,q.items[i]);
                        order  ;
                    }
                break;
                }
                            
        
        
    }
}while(menu!=4);


system("pause");
return 0;
}


int empty(struct queue *pq)
{
return((pq->front == pq->rear) ? TRUE : FALSE);
}


void cqdelete(struct queue *pq)
{
    
if (empty(pq)) {
printf("Queue is empty !");
exit(1);
}

if (pq->front == CAPACITY - 1)
 pq->front = 0;
 
else
 (pq->front)  ;
 
printf("\n -----> %s is deleted from the queue. \n\n",pq->items[pq->front]);

}


void cqinsert(struct queue *pq , char name[])
{
 printf("\n -----> %s is inserted to queue. \n\n",name);
if (pq->rear == CAPACITY - 1)
pq->rear = 0;
else
(pq->rear)  ;
if (pq->rear == pq->front) {
 printf("Queue is full !");
 exit(1);
 }

strcpy(pq->items[pq->rear],name);
 }

When q.front is greater than q.rear, case 3 (the printing) doesn't print anything.

For example after the inputs below I can't display queue elements:

  • 4 times CUSTOMER ENTRY(insert)
  • 2 times CUSTOMER EXIT(delete)
  • 2 times CUSTOMER ENTRY(insert)
  • and select Waiting Customers List ---> here is the problem: it doesn't display elements in the queue.

You can use the following inputs to apply those steps:

1
c1
1
c2
1
c3
1
c4
2
2
1
c5
1
c6
3
4

How can I display the queue, even when q.front is greater than q.rear?

CodePudding user response:

Following your suggestion, let's see what happens when we insert 4 customers, then remove 2, then insert 2 more:

Initially:

rear = 4
front = 4
queue:
  ---------- ---------- ---------- ---------- ---------- 
 |          |          |          |          |          |
  ---------- ---------- ---------- ---------- ---------- 

After 4 inserts:

rear = 3
front = 4
queue:
  ---------- ---------- ---------- ---------- ---------- 
 |   "c1"   |   "c2"   |   "c3"   |   "c4"   |          |
  ---------- ---------- ---------- ---------- ---------- 

After 2 deletes:

rear = 3
front = 1
queue:
  ---------- ---------- ---------- ---------- ---------- 
 |          |          |   "c3"   |   "c4"   |          |
  ---------- ---------- ---------- ---------- ---------- 

After 2 more inserts:

rear = 0
front = 1
queue:
  ---------- ---------- ---------- ---------- ---------- 
 |   "c6"   |          |   "c3"   |   "c4"   |   "c5"   |
  ---------- ---------- ---------- ---------- ---------- 

To print this queue, you wrote this piece of code (we are in the else of the case 3 since q.front is not CAPACITY-1):

order=1;
for(int i=q.front 1;i<=q.rear;i  ) {
  printf("[%d]-%s\n",order,q.items[i]);
  order  ;
}

i is initialized at q.front 1 = 2. The looping condition is i<=q.rear. Since q.rear is 0, this means i<=0. This is already false before the first iteration since 2<=0 is false. Thus, nothing gets printed.

Informally, the way to print the queue is:

  • print c3 (index = q.front 1)
  • print c4 (index = q.front 2)
  • print c5 (index = q.front 3)
  • print c6 (index = (q.front 4) % CAPACITY)

See what I did for c6? I wrapped around to the beginning of the queue by doing % CAPACITY. In fact, I could have added this % CAPACITY to all the other cases, it just wouldn't have changed anything since q.front 1/q.front 2/q.front 3 are less than CAPACITY.

In your code, you thought about wrapping around, but only when q.front is CAPACITY-1. Instead, you should always consider wrapping around. To do so, you can write the case 3 as follows (this is simply the algorithm corresponding to the informal steps I wrote above):

case 3:
  for (int i = q.front; i != q.rear; i = (i 1) % CAPACITY) {
    int order = (i 1-q.front CAPACITY) % CAPACITY; // (...   CAPACITY) % CAPACITY ensures a positive number
    printf("[%d]-%s\n", order, q.items[(i 1) % CAPACITY]);
  }
  break;

The idea is to start from q.front and continue looping until i is q.rear. However, while looping, we wrap around by doing i = (i 1) % CAPACITY instead of i .

Note how q.front==CAPACITY-1 is not a special case anymore: this loop will wrap around, regardless the value of q.front.

  • Related