Mailing List Example

Lecture



To complete the discussion of doubly linked lists, this section presents a simple but complete program for working with a mailing list. During operation, the entire list is stored in RAM. However, it can be saved in a file and uploaded for further work.

  / * Simple program to handle mailing lists
    illustrating working with doubly linked lists.
 * /
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 struct address {
   char name [30];
   char street [40];
   char city [20];
   char state [3];
   char zip [11]; 
   struct address * next;  / * pointer to the next entry * /
   struct address * prior;  / * pointer to the previous entry * /
 };

 struct address * start;  / * pointer to the first entry in the list * /
 struct address * last;  / * last record pointer * /
 struct address * find (char *);

 void enter (void), search (void), save (void);
 void load (void), list (void);
 void mldelete (struct address **, struct address **);
 void dls_store (struct address * i, struct address ** start,
                struct address ** last);
 void inputs (char *, char *, int), display (struct address *);
 int menu_select (void);

 int main (void)
 {
   start = last = NULL;  / * initialize start and end pointers * /

   for (;;) {
     switch (menu_select ()) {
       case 1: enter ();  / * enter address * /
         break;
       case 2: mldelete (& start, & last);  / * delete address * /
         break;
       case 3: list ();  / * list display * /
         break;
       case 4: search ();  / * address search * /
         break;
       case 5: save ();  / * write list to file * /
         break;
       case 6: load ();  / * read from disk * /
         break;
       case 7: exit (0);
     }
   }
   return 0;
 }

 / * Select user action.  * /
 int menu_select (void)
 {
   char s [80];
   int c;

   printf ("1. Entering the name \ n");
   printf ("2. Deleting a name \ n");
   printf ("3. Display the contents of the list \ n");
   printf ("4. Search \ n");
   printf ("5. Save to file \ n");
   printf ("6. Download from file \ n");
   printf ("7. Exit \ n");
   do {
     printf ("\ nYour choice:");
     gets (s);
     c = atoi (s);
   } while (c <0 || c> 7);
   return c;
 }

 / * Enter the name and addresses.  * /
 void enter (void)
 {
   struct address * info;

   for (;;) {
     info = (struct address *) malloc (sizeof (struct address));
     if (! info) {
       printf ("\ nNo free memory");
       return;
     }

     inputs ("Enter name:", info-> name, 30);
     if (! info-> name [0]) break;  / * complete input * /
     inputs ("Enter the street:", info-> street, 40);
     inputs ("Enter city:", info-> city, 20);
     inputs ("Enter State:", info-> state, 3);
     inputs ("Enter postal code:", info-> zip, 10);

     dls_store (info, & start, & last);
   } / * input cycle * /
 }

 / * The following function enters a string from the keyboard
    no longer count and prevents overflow
    lines.  In addition, it displays a hint.  * /
 void inputs (char * prompt, char * s, int count)
 {
   char p [255];

   do {
     printf (prompt);
     fgets (p, 254, stdin);
     if (strlen (p)> count) printf ("\ nNow too long \ n");
   } while (strlen (p)> count);

   p [strlen (p) -1] = 0;  / * remove the newline character * /
   strcpy (s, p);
 }

 / * Create an ordered doubly linked list.  * /
 void dls_store (
   struct address * i, / * new element * /
   struct address ** start, / * first list item * /
   struct address ** last / * last list item * /
 )
 {
   struct address * old, * p;

   if (* last == NULL) {/ * first list item * /
     i-> next = NULL;
     i-> prior = NULL;
     * last = i;
     * start = i;
     return;
   }
   p = * start;  / * start at the beginning of the list * /

   old = NULL;
   while (p) {
     if (strcmp (p-> name, i-> name) <0) {
       old = p;
       p = p-> next;
     }
     else {
       if (p-> prior) {
         p-> prior-> next = i;
         i-> next = p;
         i-> prior = p-> prior;
         p-> prior = i;
         return;
       }
       i-> next = p;  / * new first item * /
       i-> prior = NULL;
       p-> prior = i;
       * start = i;
       return;
     }
   }
   old-> next = i;  / * insert at the end * /
   i-> next = NULL;
   i-> prior = old;
   * last = i;
 }

 / * Remove item from list.  * /
 void mldelete (struct address ** start, struct address ** last)
 {
   struct address * info;
   char s [80];

   inputs ("Enter name:", s, 30);
   info = find (s);
   if (info) {
     if (* start == info) {
       * start = info-> next;
       if (* start) (* start) -> prior = NULL;
       else * last = NULL;
     }
     else {
       info-> prior-> next = info-> next;
       if (info! = * last)
           info-> next-> prior = info-> prior;
       else
         * last = info-> prior;
     }
     free (info);  / * free memory * /
   }
 }

 / * Address search.  * /
 struct address * find (char * name)
 {
   struct address * info;

   info = start;
   while (info) {
     if (! strcmp (name, info-> name)) return info;
     info = info-> next;  / * go to the next address * /
   }
   printf ("Name not found. \ n");
   return NULL;  / * no matching item * /
 }

 / * Display the entire list on the screen.  * /
 void list (void)
 {
   struct address * info;

   info = start;
   while (info) {
     display (info);
     info = info-> next;  / * go to the next address * /
   }
   printf ("\ n \ n");
 }

 / * This function performs the actual output to the screen.
    all fields of the record containing the address.  * /
 void display (struct address * info)
 {
     printf ("% s \ n", info-> name);
     printf ("% s \ n", info-> street);
     printf ("% s \ n", info-> city);
     printf ("% s \ n", info-> state);
     printf ("% s \ n", info-> zip);
     printf ("\ n \ n");
 }

 / * Search for a name in the list.  * /
 void search (void)
 {
   char name [40];
   struct address * info;

   printf ("Enter name:");
   gets (name);
   info = find (name);
   if (! info) printf ("Not found \ n");
   else display (info);
 }

 / * Save the list to disk file.  * /
 void save (void)
 {
   struct address * info;

   FILE * fp;

   fp = fopen ("mlist", "wb");
   if (! fp) {
     printf ("Unable to open file. \ n");
     exit (1);
   }
   printf ("\ nSave to file \ n");

   info = start;
   while (info) {
     fwrite (info, sizeof (struct address), 1, fp);
     info = info-> next;  / * go to the next address * /
   }
   fclose (fp);
 }

 / * Load addresses from file.  * /
 void load ()
 {
   struct address * info;
   FILE * fp;

   fp = fopen ("mlist", "rb");
   if (! fp) {
     printf ("Unable to open file. \ n");
     exit (1);
   }

   / * free memory if there is already a list in memory * /
   while (start) {
     info = start-> next;
     free (info);
     start = info;
   }

   / * reset the start and end pointers * /
   start = last = NULL;

   printf ("\ nLoad from file \ n");
   while (! feof (fp)) {
     info = (struct address *) malloc (sizeof (struct address));
     if (! info) {
       printf ("No free memory");
       return;
     }
     if (1! = fread (info, sizeof (struct address), 1, fp)) break;
     dls_store (info, & start, & last);
   }
   fclose (fp);
 } 

Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Structures and data processing algorithms.

Terms: Structures and data processing algorithms.