Category : Files from Magazines
Archive   : CUJ9206.ZIP
Filename : 1006095A

 
Output of file : 1006095A contained in archive : CUJ9206.ZIP

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

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
#include
#include
#include

#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;
}

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



  3 Responses to “Category : Files from Magazines
Archive   : CUJ9206.ZIP
Filename : 1006095A

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/