Listing 1

/* --------------------------------------------------------------

This program creates and manages a queue of strings stored as a 2D
array of chars. Each row of this array represents an entry in the
queue. The user can either add new entries to the rear of the queue
or remove old entries from the front.

-------------------------------------------------------------- */

#include  <stdio.h>
#include  <ctype.h>

#define MAX_NODES 6    /* max number of nodes in array */
#define MAX_LEN 10     /* max length of string in entry */
#define QNULL 0        /* null array index value */

#define  ADD_NODE 'A'
#define  EXIT 'E'
#define  HELP '?'
#define  REMOVE_NODE 'D'
#define  LIST_QUEUE 'L'
#define  DUMP_QUEUE 'M'

char queue[MAX_NODES + 1][MAX_LEN + 1];

unsigned int head_node = QNULL; /* start of queue */
unsigned int tail_node = QNULL; /* end of queue */

/* --------------------------------------------------------------- */

main()
{
      unsigned int i, node, node_number;
      int inchar = 'x';       /* force initial prompt */
      int done = 0;

/* --------------------------------------------------------------- */

      while (!done) {
             if (inchar != ' ')
                    printf("\nEnter Action Code (%c for help): ", HELP);
             switch(toupper(inchar = getchar())) }

/* -------------------------------------------------------------- */

      case EXIT:
             done = 1;
             break;

/* --------------------------------------------------------------- */
      default:
             printf("\n Invalid command. Please try again\n");
             break;

/* --------------------------------------------------------------- */

      case HELP:
             printf("\n The action codes are:\n");
             printf("\t%c - Produces this help message\n", HELP);
             printf("\t%c - Exit this program\n", EXIT);
             printf("\t%c - Add a new node to the tail\n", ADD_NODE);
             printf("\t%c - Remove head node\n", REMOVE_NODE);
             printf("\t%c - List all entries in the queue\n", LIST_QUEUE);
             printf("\t%c - List contents of queue array\n", DUMP_QUEUE);
             break;

/* ---------------------------------------------------------------- */

      case '\n':      /* ignore white space on input */
      case ' ' :
      case '\t':
      case '\v':
      case '\f':
             inchar = ' ';   /* indicate white space input */
             break;

/* --------------------------------------------------------------- */

ADD_NODE: The steps to add a new node to the end of the queue are:

A.  If queue full, complain and get out. This can happen in one of two
   ways: array element 1 is the head of the queue and array element
   MAX_NODES represent the tail or; the queue is wrapped in a
   circular manner and exactly fills the array.

B.  If this is the first node, make it the head and tail. Otherwise,
   if the current tail is the last element, wrap to element 1.
   Otherwise, go to the next element beyond the current tail.

C.  Have a new node so fill it with data.

/* --------------------------------------------------------------- */

      case ADD_NODE:

/*A*/          if  ((head_node == 1 && tail_node == MAX_NODES) ||
                 head_node == tail_node + 1) {
                    printf("\n   Queue is full\n");
                    break;
             }

/*B*/          if  (head_node == QNULL) {
                    head_node = tail_node = 1;
             }
             else if (tail_node == MAX_NODES) {
                    tail_node = 1;
             }
             else {
                    ++tail_node;
             }

/*C*/           printf("\n   Enter new node's value: ");
             scanf("%10s", queue[tail_node]);
             printf("\n   Node added\n");
             break;

/* --------------------------------------------------------------

REMOVE_NODE: The steps to remove the tail node are:

A.  Complain if list empty.

B.  Adjust the head and tail nodes as follows: If this is the only
   node in the queue, make the head and tail both null. Otherwise, if
   this node is stored in the last array element, wrap the new head
   to element 1. Otherwise, make the new head one more than the old
   one.

-------------------------------------------------------------- */

      case REMOVE_NODE:

/*A*/          if  (head_node == QNULL) {
                    printf("\n Queue is empty\n");
                    break;
             }

/*B*/          queue[head_node][0] = '\0';   /* overwrite string */
             if (head_node == tail_node) {
                    head_node = tail_node = QNULL;
             }
             else if (head_node == MAX_NODES) {
                    head_node = 1;
             }
             else {
                    ++head_node;
             }
             printf("\n Node removed\n");
             break;

*/ ---------------------------------------------------------------

LIST_QUEUE: The steps to display all nodes in the queue are:

A.  Complain if queue empty.

B.  Traverse queue starting at the head node displaying each node's
   string and the logical node number. Need to wrap if queue is
   stored in a circular manner.

-------------------------------------------------------------- */

      case LIST_QUEUE:

/*A*/          if  (head_node == QNULL) {
                    printf("\n Queue is empty\n");
                    break;
            }

/*B*/          printf("\n    Queue nodes are as follows:\n");
            node = head_node;
            node_number = 0;
            while (1) {
                    printf("\tNode %u => %s\n", ++node_number, queue[node]);
                    if (node == tail_node)
                           break;

                    if (node == MAX_NODES) {
                           node = 1;
                    }
                    else {
                           ++node;
                    }
             }

             break;

/* --------------------------------------------------------------

DUMP_QUEUE: The steps to dump all 'nodes' in the queue array are:

A.  Traverse queue array starting at [1] displaying the array element
   number and corresponding string. No need to wrap as this is a
   physical dump, not a logical one.

-------------------------------------------------------------- */

      case DUMP_QUEUE:

/*A*/          printf("\n    [%d] is head_node, [%d] is tail_node\n",
                   head_node, tail_node);
            if (head_node == QNULL) {
                   printf("\n   Queue is empty\n");
            }

            printf("\n   Queue array nodes are as follows:\n");
            for (i = 1; i <= MAX_NODES; ++i) {
                   printf("\t[%u] => %s\n", i, queue[i]);
            }

            break;

*/ -------------------------------------------------------------- */

            }

      }

      return (0);
}
*/ -------------------------------------------------------------- */

/* End of File */