home *** CD-ROM | disk | FTP | other *** search
-
- /* --------------------------------------------------------------
-
- This program creates and manages a queue of strings stored as a
- linked list. Each node of this list 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>
- #include <stdlib.h>
- #include <string.h>
-
- #define ADD_NODE 'A'
- #define EXIT 'E'
- #define HELP '?'
- #define REMOVE_NODE 'D'
- #define LIST_QUEUE 'L'
-
- #define MAX_LEN 10 /* max length of string in entry */
-
- typedef struct node {
- struct node *pfwd; /* ptr to next node in queue */
- char *pstring; /* ptr to node's string value */
- } Node;
-
- Node *get_free_node(void);
- void put_free_node(Node *pnode);
-
- void help(void); /* action functions */
- void add_node(const char *string);
- void remove_node(char *string);
- void list_queue(void);
-
- Node *proot_node = NULL; /* start of data queue */
- Node *ptail_node = NULL; /* end of data queue */
- Node *pfree_node = NULL; /* next free node */
-
- main()
- {
- int inchar = 'x'; /* force initial prompt */
- char string[MAX_LEN + 1];
-
- while (1) {
- if (inchar != ' ')
- printf("\nEnter Action Code (%c for help): ", HELP);
- switch(toupper(inchar = getchar())) {
-
- default:
- printf("\n Invalid command. Please try again\n");
- break;
-
- case HELP:
- help();
- break;
-
- case EXIT:
- exit(EXIT_SUCCESS);
- break;
-
- case '\n': /* ignore white space on input */
- case ' ' :
- case '\t':
- case '\v':
- case '\f':
- inchar = ' '; /* indicate white space input */
- break;
-
- case ADD_NODE:
- printf("\n Enter new node's value: ");
- scanf("%10s", string);
- add_node(string);
- break;
-
- case REMOVE_NODE:
- remove_node(string);
- if (string[0] != '\0') {
- printf(" String stored in removed node = %s\n",
- string);
- }
- break;
-
- case LIST_QUEUE:
- list_queue();
- break;
- }
- }
-
- return 0;
- }
-
- void help(void)
- {
- 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);
- }
-
- /* --------------------------------------------------------------
-
- FUNCTION ADD_NODE: The steps to add a new node to the end of the
- queue are:
-
- A. Get a free node from free node list. If no more, complain and
- get out.
-
- B. Get space for new node's string. If no more, complain and get
- out releasing node allocated in A.
-
- C. Initialize new node's string pointer and copy user string to
- allocated space.
-
- D. If this is the first node, make it the head and tail. Otherwise,
- make it the new tail node. Make forward pointer null.
-
- -------------------------------------------------------------- */
-
- void add_node(const char *string)
- {
- Node *pnew_node; /* ptr to new node */
- char *pstring; /* ptr to alloced string space */
-
- /*A*/ pnew_node = get_free_node();
- if (pnew_node == NULL) {
- printf("\n No nodes available\n");
- return;
- }
-
- /*B*/ pstring = malloc(strlen(string) + 1);
- if (pstring == NULL) {
- printf("\n No string space available\n");
- put_free_node(pnew_node);
- return;
- }
-
- /*C*/ pnew_node->pstring = pstring;
- strcpy(pnew_node->pstring, string);
-
- /*D*/ if (proot_node == NULL) {
- proot_node = pnew_node;
- }
- else {
- ptail_node->pfwd = pnew_node;
- }
-
- ptail_node = pnew_node;
- pnew_node->pfwd = NULL;
-
- printf("\n Node added\n");
- }
-
- /* --------------------------------------------------------------
-
- FUNCTION REMOVE_NODE: The steps to remove the tail node are:
-
- A. Complain if queue empty.
-
- B. If this is the only node in the queue, clear root and tail
- pointers. Otherwise, adjust root pointer to new first node.
-
- C. Save a copy of the string being released and free the node.
-
- -------------------------------------------------------------- */
-
- void remove_node(char *string)
- {
- Node *ptmp_node = proot_node;
-
- /*A*/ if (proot_node == NULL) {
- printf("\n Queue contains no nodes\n");
- *string = '\0';
- return;
- }
-
- /*B*/ if (proot_node == ptail_node) {
- proot_node = ptail_node = NULL;
- }
- else {
- proot_node = proot_node->pfwd;
- }
-
- /*C*/ strcpy(string, ptmp_node->pstring);
- free(ptmp_node->pstring);
- put_free_node(ptmp_node);
- printf("\n Node removed\n");
- }
-
- /* --------------------------------------------------------------
-
- FUNCTION 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.
-
- -------------------------------------------------------------- */
-
- void list_queue(void)
- {
- Node *ptmp_node;
- unsigned int node_number;
-
- /*A*/ if (proot_node == NULL) {
- printf("\n Queue contains no nodes\n");
- return;
- }
-
- printf("\n Queue nodes are as follows:\n");
-
- /*B*/ ptmp_node = proot_node;
- node_number = 0;
- while (ptmp_node != NULL) {
- printf("\tNode %u => %s\n", ++node_number, ptmp_node->pstring);
- ptmp_node = ptmp_node->pfwd;
- }
- }
-
- /* --------------------------------------------------------------
-
- FUNCTION GET_FREE_NODE: The steps to get a node from the free node
- list are:
-
- A. If the free node list is empty, get memory for a new node and
- return its address.
-
- B. Else remove the first node from the free list and use that.
-
- -------------------------------------------------------------- */
-
- Node *get_free_node(void)
- {
- Node *pnew_node;
-
- /*A*/ if (pfree_node == NULL) {
- pnew_node = malloc(sizeof(Node));
- }
- /*B*/ else {
- pnew_node = pfree_node;
- pfree_node = pfree_node->pfwd;
- }
-
- return pnew_node;
- }
-
- /* --------------------------------------------------------------
-
- FUNCTION PUT_FREE_NODE: The steps to release an active node and add
- it to the front of the free list are:
-
- A. Insert the node at the start of the free node list.
-
- -------------------------------------------------------------- */
-
- void put_free_node(Node *pnode)
- {
- /*A*/ pnode->pfwd = pfree_node;
- pfree_node = pnode;
- }
-
- /* ----------------------------------------------------------- */
-
-