Link to home
Start Free TrialLog in
Avatar of siasd
siasd

asked on

ADDING A SORT FUNCTION

I have written this address book program, but I can't figure out how to add a sort function.  I have a very busy schedule at work and I don't have time to write the code.  So I'm willing to give extra point to get the code written and working correctly.  I'm also working on my class reunion and I wanted to write this program to simplifiy updating my old high school classmates addresses.
Can anyone help me. Thanks in advance. SIASD

* * * * * * * * * * * * *

/* Address Book  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>


#define LIST     200                     /* Max number of records in database */
#define TRUE       1
#define FALSE      0
#define NAME      13
#define STREET  22
#define CITY        12
#define STATE     3
#define ZIPCODE  6
#define PHONE   12
#define DEBUG     FALSE

#define DEBUGFILE                  "debug.txt"
#define PRINTER_PORT            "LPT1:"

struct namestr {
                  char fname[NAME + 1];
                  char lname[NAME + 1];
               };

struct address {
                  unsigned short recordnum;
                  struct         namestr PERSON;
                  char           street[STREET + 1];
                  char           city[CITY + 1];
                  char           state[STATE + 1];
                  char           zipcode[ZIPCODE + 1];
                  char           phone[PHONE +1];
               };


static int  add(struct address BOOK[], int *count);
static void change(struct address BOOK[], int *count);
static void del(struct address BOOK[], int *count);
static void inputs(char *prompt, char *str, unsigned int max);
static void help();
static int  load(struct address BOOK[], int *count, char *fname, int lastfile);
static char menu();
static void printlist(struct address BOOK[], int *count);
static void print_rec(int i, struct address BOOK[]);
static void save(struct address BOOK[], int *count, char *fname, int lastfile);

/*------------------------------------------------------------------------------
FUNCTION:   main
 PURPOSE:   This function drives the entire program.
            A menu is displayed, then a call to the appropriate function.
------------------------------------------------------------------------------*/
void main()
{
   static struct address BOOK[LIST];         /* Array of address book records */

   static int count = 0;             /* Counter for number of records in list */
   static char fname[20];
   static int lastfile = FALSE;


   for(;;)
   {
      printf("\n\nEnter the letter in brackets to activate your choice.");
      printf("\n\n\t\tMenu\n");
      switch( menu() )   /* Call to display menu, returns character */
      {
         case 'L':
                     printf("\n----- LOADING A FILE -----\n");
                     lastfile = load(BOOK, &count, fname, lastfile);
                     break;
         case 'S':
                     printf("\n----- SAVING A RECORD -----\n");
                     save(BOOK, &count, fname, lastfile);
                     break;
         case 'A':
                     printf("\n----- ADDING A NEW RECORD -----\n");
                     lastfile = add(BOOK, &count);
                     break;
         case 'C':
                     printf("\n----- CHANGING A RECORD -----\n");
                     change(BOOK, &count);
                     break;
         case 'D':
                     printf("\n----- DELETING A RECORD -----\n");
                     del(BOOK, &count);
                     break;
         case 'P':
                     printf("\n----- PRINTING THE RECORDS -----\n");
                     printlist(BOOK, &count);
                     break;
         case 'H':
                     //clrscr();
                     printf("\n----- HELP MENU -----\n");
                     help();
                     break;

         case 'Q':
                     exit(0);
      }
   }
}
/*------------------------------------------------------------------------------
FUNCTION:   add
 PURPOSE:   This function adds a record to the database.
            First the record number is assigned,
            then inputs is called passing the user prompt, destination, and
            max string length.
------------------------------------------------------------------------------*/
static int add(struct address BOOK[], int *count)
{
   if(*count > LIST)                                   /* If too many records */
   {
      printf("\n\tList full!  Save & Quit the program.");
   }
   else                                    /* Else assign record to structure */
   {
      fflush(stdin);
      BOOK[*count].recordnum = (unsigned short)(*count +1);
      inputs("\n\tEnter first name: ",    BOOK[*count].PERSON.fname, NAME);
      inputs("\tEnter last name: ",         BOOK[*count].PERSON.lname, NAME);
      inputs("\tEnter street address: ",  BOOK[*count].street, STREET);
      inputs("\tEnter city: ",            BOOK[*count].city, CITY);
      inputs("\tEnter state: ",        BOOK[*count].state, STATE);
      inputs("\tEnter zipcode: ", BOOK[*count].zipcode, ZIPCODE);
      inputs("\tEnter phone number: ", BOOK[*count].phone, PHONE);

      (*count)++;
   }
   return TRUE;
}
/*------------------------------------------------------------------------------
FUNCTION:   change
 PURPOSE:   This functions changes a database record.
            The user is prompted for the record number to change.
            Then a search for the record number is conducted.
            If no match is found, the appropriate message is displayed.
            If there is a match, then the record is displayed,
            and the user is asked which element to change, or to return
            to the main menu.
------------------------------------------------------------------------------*/
static void change(struct address BOOK[], int *count)
{
   unsigned short chrec = 0;
   char ch = ' ';
   int i, quit = FALSE;
   static int find = TRUE, change = FALSE;
   char choice;

   printf("Please enter the number of the record you wish to change: ");
   scanf("%d", &chrec);
   do
   {
      for(i = 0; i < *count; i++)       /* Loop to search through all records */
      {
         if(BOOK[i].recordnum == chrec && quit != TRUE)/* If record number matches */
         {
            print_rec(i, BOOK);                      /* Display single record */
            find = TRUE;
            do
            {                        /* Ask with element user wants to change */
               printf("\n\n\tWhich record do you wish to change?");
               printf("\n\t(F)irst name\n\t(L)astname\n\t(A)ddress");
               printf("\n\t(C)ity\n\t(S)tate\n\t(Z)ipcode\n\t(P)hone\n\t(R)eturn to menu");
               printf("\n\n\tEnter your choice: ");
               fflush(stdin);
               gets(&choice);
            } while( !strchr( "FLACSZPR", toupper(choice) ) );

            switch( toupper(choice) )              /* Input and assign change */
            {
               case 'F':
                     inputs("\tEnter first name: ",      BOOK[i].PERSON.fname, NAME);
                     change = TRUE;
                     break;
               case 'L':
                     inputs("\tEnter last name: ",         BOOK[i].PERSON.lname, NAME);
                     change = TRUE;
                     break;
               case 'A':
                     inputs("\tEnter street address: ",  BOOK[i].street, STREET);
                     change = TRUE;
                     break;
               case 'C':
                     inputs("\tEnter city: ",            BOOK[i].city, CITY);
                     change = TRUE;
                     break;
               case 'S':
                     inputs("\tEnter state: ",        BOOK[i].state, STATE);
                     change = TRUE;
                     break;
               case 'Z':
                     inputs("\tEnter zip code: ", BOOK[i].zipcode, ZIPCODE);
                     change = TRUE;
                     break;
                case 'P':
                     inputs("\tEnter telephone number: ", BOOK[i].phone, PHONE);
                     change = TRUE;
                     break;
               case 'R':
                     quit = TRUE;
            }
         }
      }
   }while(quit != TRUE);
   if(change == TRUE)
   {
      printf("\nThe change was successful...");
   }
   else
   {
      if(find == FALSE)
      {
         printf("\nRecord number not found.");
      }
      printf("\nNo changes were made...");
   }
   printf("\nPress enter to return to main menu...");
   getch();
   //clrscr();
   fflush(stdin);
   //scanf("%c", &ch);
}
/*------------------------------------------------------------------------------
FUNCTION:   del
 PURPOSE:   This function flags a record for deletion,
            and re-initialises the record numbers.
            The user is asked which record to delete,
            If there is a match, then confirmation is required,
            If deletion is confirmed, record is flagged.
            Appropriate messages are displayed after users options.
------------------------------------------------------------------------------*/
static void del(struct address BOOK[], int *count)
{
   unsigned short chrec = 0;
   int i, j, done = 0;
   char answer;

   printf("\n\nPlease enter the number of the record you wish to delete: ");
   fflush(stdin);
   scanf("%d", &chrec);
   for(i = 0; i < *count, done == FALSE; i++)/* Loop to search through all records */
   {
      if(BOOK[i].recordnum == chrec)              /* If record number matches */
      {
         print_rec(i, BOOK);                         /* Display single record */
         do
         {                                                    /* Confirmation */
            printf("\n\nYou have chosen to delete record number ");
            printf("%d.  Are you sure? Y or N: ", BOOK[i].recordnum);
            fflush(stdin);
            scanf("%c", &answer);
         } while( !strchr( "YN", toupper(answer) ) );

         if( toupper(answer) == 'Y')                        /* If answer is Y */
         {
            BOOK[i].recordnum = 0;                       /* Flag for deletion */

            for(j = 0; j < *count; j++)        /* Loop to include all records */
            {
               if(BOOK[j].recordnum != 0 && BOOK[j].recordnum > chrec)
               {                                     /* Update record numbers */
                  BOOK[j].recordnum -= (unsigned short)1;
               }
            }
            printf("\n\nThe record has been flagged for deletion...\nThe actual ");
            printf("deletion will occur the next time the file is saved to disk");
            done = TRUE;
         }
         else
         {
            printf("Okay, deletion has been cancelled, returning to menu...");
            done = TRUE;
         }
      }
   }
   if(done == FALSE)
   {
      printf("record not found");
   }
}

/*------------------------------------------------------------------------------
FUNCTION:   help
 PURPOSE:   This function brings up a help menu for the user to explain
            the features of this program.
------------------------------------------------------------------------------*/
static void help()
{
   //char ch;
   printf("Enter the letter in brackets to activate your choice.\n");
   printf("What would you like help with?");

   switch( menu() )
   {
      case 'L':
            printf("\n----- LOADING A FILE -----\n");
            printf("This option allows you to enter the name of a file which will then be");
            printf("\nopened and read into memory.\n\n");
            printf("You can use this option more than once in order to read several files into\n");
            printf("the program, in which case the contents of each succeeding file are\n");
            printf("added to the end of the same address book already in memory.\n");
            break;
      case 'S':
            printf("\n----- SAVING A RECORD -----\n");
            printf("This option allows you to write the contents if the address book from\n");
            printf("memory to disk.\n\n");
            printf("Any records that have been flagged for deletion will not be saved to disk.\n\n");
            printf("When this option has been chosen, you will be asked if you wish to \n");
            printf("overwrite the last filename that was opened.  If you do not wish to do\n");
            printf("this, you can enter the name of a new file which will then be the\n");
            printf("destination of the updated address book.\n");
            break;
      case 'A':
            printf("\n----- ADDING A NEW RECORD -----\n");
            printf("This option allows you to enter new records which will be added to the\n");
            printf("address book in memory.\n\n");
            printf("You can enter new records either before or after file(s) have been loaded\n");
            printf("into the address book.\n\n");
            printf("You can create a new file by adding records with this option, then saving\n");
            printf("them as a new file by using the SAVE FILE option, without having to load\n");
            printf("any files.\n");
            break;
      case 'C':
            printf("\n----- CHANGING A RECORD -----\n");
            printf("Enter a record number, then you can change either name, address or both.\n\n");
            printf("The record details for the requested record is displayed on the screen\n");
            printf("and then you enter which type to change.\n\n");
            printf("All change operations affect only the address book stored in memory - that\n");
            printf("is, until the user saves the list to disk with the SAVE FILE option.\n");
            break;
      case 'D':
            printf("\n----- DELETING A RECORD -----\n");
            printf("After selecting this option, you can enter the record number you wish to\n");
            printf("delete from the address book.\n\n");
            printf("When the record number has been entered, the record details are\n");
            printf("displayed on screen and you are requested for confirmation.\n");
            printf("If you choose not not to delete, then you're returned to the main menu.\n");
            printf("If you confirm deletion, the record number is set flagged for deletion.\n");
            printf("The actual deletion occurs next time the file is saved to disk.\n");
            break;
      case 'P':
            printf("\n----- PRINTING THE RECORDS -----\n");
            printf("This option allows you to choice of sending the output to the screen, or\n");
            printf("to the printer.\n");
            break;
      case 'H':
            printf("\n----- THE HELP MENU -----\n");
            printf("This option displays a help menu.  When you enter a letter in brackets,\n");
            printf("you can recieve info on the particular option.\n");
            break;
      case 'Q':
            printf("\n----- QUITING THIS PROGRAM -----\n");
            printf("This option allows you to exit this program.\n");
            break;
      }

   fflush(stdin);
   printf("\n\nPress enter to return to the main menu...");
   getch();
   //scanf("%c", &ch);
   //clrscr();
}
/*------------------------------------------------------------------------------
FUNCTION:   input
 PURPOSE:   This function displays a prompt, and validates the response
            by length only.
            Then string copys the valid response to the pointer passed.
------------------------------------------------------------------------------*/
static void inputs(char *prompt, char *str, unsigned int max)
{
   char temp[80];

   printf(prompt);
   do
   {
      gets(temp);
      if(strlen(temp) > max)
      {
         printf("\a\n\tToo long, please re-enter: ");
      }
   } while(strlen(temp) > max);

   strcpy(str, temp);
}
/*------------------------------------------------------------------------------
FUNCTION:   load
 PURPOSE:   This function loads a database into memory.
            The user is asked for a file name, which is validated.
            If this is not the first file to be loaded,
            Then a new record number is assigned to be added to the current
            database in memory.
            Otherwise, the records are copied as is.
            The process is validated, and appropriate errors display a message.
------------------------------------------------------------------------------*/
static int load(struct address BOOK[], int *count, char *fileptr, int lastfile)
{
   FILE *fp;
   static struct address TEMP;
   char ch = ' ';
   printf("\tEnter the name of the input file: ");
   scanf("%s", fileptr);

   if( (fp = fopen(fileptr, "rb") ) == NULL )   /* Open the file to read from */
   {
      fprintf(stderr, "\nFile open error on <%s>", fileptr);
   }
   else
   {
      if(lastfile == TRUE)                    /* If there are already records */
      {
         fread(&TEMP, sizeof(struct address), 1, fp);
         while(!ferror(fp) && ! feof(fp) && *count < LIST)
         {
          BOOK[*count] = TEMP;                    /* Assign new record number */
          BOOK[*count].recordnum      = (unsigned short)(*count +1);
          (*count)++;

          fread(&TEMP, sizeof(struct address), 1, fp);
         }
      }
      else
      {
                                  /* Read records from database one at a time */
                                   /* and increment number of records in list */
         fread(&BOOK[*count], sizeof(struct address), 1, fp);
         while(!ferror(fp) && ! feof(fp) && *count < LIST)
         {
            (*count)++;
            fread(&BOOK[*count], sizeof(struct address), 1, fp);
         }
      }

      if( ferror(fp) )
      {
         fprintf(stderr, "File read error has occurred.");
      }
      else if(*count >= LIST)                      /* not all records may fit */
      {
         fprintf(stderr, "\n\tList full!  Quit the program.");
      }
      else
      {
         printf("\n\tFile <%s> loaded into memory.", fileptr);
         lastfile = TRUE;
      }

      fclose(fp);
   }
   printf("\nPress enter to continue...");
   getch();
   //clrscr();
   fflush(stdin);
   //scanf("%c", &ch);
   return lastfile;
}
/*------------------------------------------------------------------------------
FUNCTION:   menu
 PURPOSE:   Display menu options and validate input choices
------------------------------------------------------------------------------*/
static char menu()
{
   static char ch;

   do
   {
      printf("\n\t(L)oad a file");
      printf("\n\t(S)ave a file");
      printf("\n\t(A)dd a record");
      printf("\n\t(C)hange a record");
      printf("\n\t(D)elete a record");
      printf("\n\t(P)rint file");
      printf("\n\t(H)elp");
      printf("\n\t(Q)uit");

      printf("\n\n\tEnter your choice: ");
      fflush(stdin);
      scanf("%c", &ch);
      if( !strchr( "LSACDPHQ", toupper(ch) )  )
      {
         printf("\nYou have entered an invalid key, please try again...");
      }
   } while( !strchr( "LSACDPHQ", toupper(ch) )  );

   return (char)toupper(ch);
}
/*------------------------------------------------------------------------------
FUNCTION:   printlist
 PURPOSE:   Prints database to screen or printer.
------------------------------------------------------------------------------*/
static void printlist(struct address BOOK[], int *count)
{
   FILE *handle;
   int i = 0, j = 0, printer = 0, counter = 0;
   //char ch;
   do
   {
      printf("\n Do you want to send output to the printer? ");
      printf("\nType 0 to print screen, 1 to print to printer: ");
      scanf("%d", &printer);
      fflush(stdin);
      if(printer == TRUE)
      {
                                                   /* Open channel to printer */
         handle = fopen("PRINTER_PORT", "wt");
#if DEBUG
         freopen(DEBUGFILE, "wt", handle);   /* Redirect the standard printer */
#endif                                                    /* stream to a file */
      }

      if(printer == FALSE)
      {
         handle = stdout;                          /* Assign handle to screen */
      }
   } while( printer != 0 && printer != 1);

                                                               /* Print title */
   fprintf(handle, "\nREC # LAST         FIRST           ADDRESS");
   fprintf(handle, "            CITY      STATE   ZIPCODE   TELEPHONE\n");
   for(j = 0; j <92; j++)
   {
      fprintf(handle, "%c", '-');
   }

   for(j = 0; j < *count; j++)                 /* Loop to include all records */
   {

      if(counter >= 20)                                     /* If end of page */
      {
         if(handle == stdout)                        /* If printing on screen */
         {
            printf("\n----- Press any key to continue -----\n");
            getch();
            fflush(stdin);
         }
         else
         {
            fputc('\f', handle);              /* Else formfeed at end of page */
         }
                                                               /* Print title */
          fprintf(handle, "\nREC # LAST         FIRST           ADDRESS");
          fprintf(handle, "            CITY      STATE   ZIPCODE   TELEPHONE\n");
         for(i = 0; i < 92; i++)
         {
            fprintf(handle, "%c", '-');
         }
         counter = 0;
      }                                                         /* Print body */
      fprintf(handle, "\n%4d  ",    BOOK[j].recordnum);
      fprintf(handle, "%-13s%-13s", BOOK[j].PERSON.lname,
                                    BOOK[j].PERSON.fname);
      fprintf(handle, "%-21s",      BOOK[j].street);
      fprintf(handle, "%-12s ",     BOOK[j].city);
      fprintf(handle, "%-5s",       BOOK[j].state);
      fprintf(handle, "  %-1s",       BOOK[j].zipcode);
      fprintf(handle, "  %s",       BOOK[j].phone);
      counter++;
   }
   if(printer == TRUE)                             /* If outputing to printer */
      {
         fputc('\f', handle);                                    /* Form feed */
         fclose(handle);                           /* Close stream to printer */
      }
   printf("\n\nReturning to menu, press enter to continue...\n");
   getch();
   //scanf("%c", &ch);
   //clrscr();
}
/*------------------------------------------------------------------------------
FUNCTION:   print_rec
 PURPOSE:   Prints a single record to the screen.
------------------------------------------------------------------------------*/
static void print_rec(int i, struct address BOOK[])
{
   int j = 0;
   printf("\nREC # LAST         FIRST           ADDRESS");       /* Print title */
   printf( "            CITY      STATE   ZIPCODE   TELEPHONE\n");

   for(j = 0; j < 92; j++)
   {
      printf("%c", '-');
   }                                                            /* Print body */
   printf("\n%4d  ",    BOOK[i].recordnum);
   printf("%-13s%-13s", BOOK[i].PERSON.lname,
                        BOOK[i].PERSON.fname);
   printf("%-21s",      BOOK[i].street);
   printf("%-12s",      BOOK[i].city);
   printf("%-5s",       BOOK[i].state);
   printf("  %-1s",       BOOK[i].zipcode);
   printf("  %s",       BOOK[i].phone);
}
/*------------------------------------------------------------------------------
FUNCTION:   save
 PURPOSE:   Rewrites database to disk.
------------------------------------------------------------------------------*/
static void save(struct address BOOK[], int *count, char *fileptr, int lastfile)
{
   FILE *fp;
   int i = 0, file_error = FALSE;
   char answer = 0;
                          /* If lastfile is true and there's a file in memory */
   if(lastfile == TRUE && *fileptr != '\0')
   {
      do
      {                                                       /* Confirmation */
         printf("Do you wish to overwrite the last filename opened? Y or N: ");
         fflush(stdin);
         scanf("%c", &answer);
      } while( !strchr( "YN", toupper(answer) ) );
   }

   if( toupper(answer) == 'Y')                              /* If answer is Y */
   {
      if( (fp = fopen(fileptr, "wb") ) == NULL)  /* Open the file to write to */
      {
         fprintf(stderr, "\nFile open error on <%s>", *fileptr);
         file_error = TRUE;
      }
   }
   else
   {
      printf("\n\tEnter the new file to be saved: ");
      scanf("%s", fileptr);
      if( (fp = fopen(fileptr, "wb") ) == NULL)  /* Open the file to write to */
      {
         fprintf(stderr, "\nFile open error on <%s>", *fileptr);
         file_error = TRUE;
      }
   }

   if(file_error == FALSE)
   {
      for(i = 0; i < *count; i++)                     /* Loop for all records */
      {
         if(BOOK[i].recordnum > 0)
         {
            fwrite(&BOOK[i], sizeof(struct address), 1, fp); /* Write records */
         }                                           /* to disk one at a time */
      }
      fprintf(stdout, "\nFile <%s> saved...\n", fileptr);
      fclose(fp);
   }
}
Avatar of Koma666
Koma666
Flag of Germany image

Here is your code :-)
Order function included just compile, i have integrated the new functions in the menu.

Have fun :-)
 
/* Address Book  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#define LIST 200 /* Max number of records in database */
#define TRUE 1
#define FALSE 0
#define NAME 13
#define STREET 22
#define CITY 12
#define STATE 3
#define ZIPCODE 6
#define PHONE 12
#define DEBUG FALSE
#define DEBUGFILE "debug.txt"
#define PRINTER_PORT "LPT1:"
struct namestr {
                 char fname[NAME + 1];
                 char lname[NAME + 1];
              };
struct address {
                 unsigned short recordnum;
                 struct         namestr PERSON;
                 char           street[STREET + 1];
                 char           city[CITY + 1];
                 char           state[STATE + 1];
                 char           zipcode[ZIPCODE + 1];
                 char           phone[PHONE +1];
              };
static int  add(struct address BOOK[], int *count);
static void change(struct address BOOK[], int *count);
static void del(struct address BOOK[], int *count);
static void inputs(char *prompt, char *str, unsigned int max);
static void help();
static int  load(struct address BOOK[], int *count, char *fname, int lastfile);
static char menu();
static void printlist(struct address BOOK[], int *count);
static void print_rec(int i, struct address BOOK[]);
static void save(struct address BOOK[], int *count, char *fname, int lastfile);
static int order(struct address BOOK[],  int *count);

/*------------------------------------------------------------------------------
FUNCTION:   main
PURPOSE:   This function drives the entire program.
           A menu is displayed, then a call to the appropriate function.
------------------------------------------------------------------------------*/
int main(void)
{
  static struct address BOOK[LIST];         /* Array of address book records */
  static int count = 0;             /* Counter for number of records in list */
  static char fname[20];
  static int lastfile = FALSE;
  for(;;)
  {
     printf("\n\nEnter the letter in brackets to activate your choice.");
     printf("\n\n\t\tMenu\n");
     switch( menu() )   /* Call to display menu, returns character */
     {
        case 'L':
                    printf("\n----- LOADING A FILE -----\n");
                    lastfile = load(BOOK, &count, fname, lastfile);
                    break;
        case 'S':
                    printf("\n----- SAVING A RECORD -----\n");
                    save(BOOK, &count, fname, lastfile);
                    break;
        case 'A':
                    printf("\n----- ADDING A NEW RECORD -----\n");
                    lastfile = add(BOOK, &count);
                    break;
        case 'C':
                    printf("\n----- CHANGING A RECORD -----\n");
                    change(BOOK, &count);
                    break;
        case 'D':
                    printf("\n----- DELETING A RECORD -----\n");
                    del(BOOK, &count);
                    break;
        case 'P':
                    printf("\n----- PRINTING THE RECORDS -----\n");
                    printlist(BOOK, &count);
                    break;
        case 'H':
                    //clrscr();
                    printf("\n----- HELP MENU -----\n");
                    help();
                    break;
        case 'O':
                    printf("\n----- SORTING THE RECORDS -----\n");
                    order(BOOK,&count);
                    break;
        case 'Q':
                    exit(0);
     }
  }
 return true;
}

static int order( struct address BOOK[],  int *count)
{
        static char ch;
        do
        {
             printf("\n\t(C)ity");
             printf("\n\t(F)irst name");
             printf("\n\t(L)ast name");
             printf("\n\t(S)tate");
             printf("\n\n\tEnter your choice: ");
             fflush(stdin);
             scanf("%c", &ch);
             if( !strchr( "CFLS", toupper(ch) )  )
             {
                  printf("\nYou have entered an invalid key, please try again...");
             }
        } while( !strchr( "CFLS", toupper(ch) )  );


      bool isFinished;
      bool bigger;
      struct address Temp;
      int iPos;
      
      switch( toupper(ch) )   /* Call to display menu, returns character */
     {
        case 'C':
                    printf("\n----- ORDER BY CITY -----\n");
                    break;
        case 'F':
                    printf("\n----- ORDER BY FIRST NAME -----\n");
                    break;
        case 'L':
                    printf("\n----- ORDER BY LAST NAME -----\n");
                    break;
        case 'S':
                    printf("\n----- ORDER BY STATE -----\n");
                    break;
            case 'R':
                              return 0;
     }      

      do
      {
            isFinished = true;
            for( iPos=0; iPos < ( *count - 1); iPos++ )
            {
                  bigger = false;
                  switch( toupper(ch) )   /* Call to display menu, returns character */
                  {
                  case 'C':
                                    //printf("\n----- ORDER BY CITY -----\n");
                                    if( strcmp(BOOK[iPos].city,BOOK[iPos+1].city) > 0 )
                                          bigger=true;
                                    break;
                  case 'F':
                                    //printf("\n----- ORDER BY FIRST NAME -----\n");
                                    if( strcmp(BOOK[iPos].PERSON.fname,BOOK[iPos+1].PERSON.fname) > 0 )
                                          bigger=true;
                                    break;
                  case 'L':
                                    //printf("\n----- ORDER BY LAST NAME -----\n");
                                    if( strcmp(BOOK[iPos].PERSON.lname,BOOK[iPos+1].PERSON.lname) > 0 )
                                          bigger=true;
                                    break;
                  case 'S':
                                    //printf("\n----- ORDER BY STATE -----\n");
                                    if( strcmp(BOOK[iPos].state,BOOK[iPos+1].state) > 0 )
                                          bigger=true;
                                    break;
                  }      
                  if(bigger)
                  {
                        Temp = BOOK[iPos];
                        BOOK[iPos] = BOOK[iPos+1];
                        BOOK[iPos+1] = Temp;
                        isFinished = false;
                  }
            }
      } while( !isFinished );
      printf("\nfinished");
      return true;
}



/*------------------------------------------------------------------------------
FUNCTION:   add
PURPOSE:   This function adds a record to the database.
           First the record number is assigned,
           then inputs is called passing the user prompt, destination, and
           max string length.
------------------------------------------------------------------------------*/
static int add(struct address BOOK[], int *count)
{
  if(*count > LIST)                                   /* If too many records */
  {
     printf("\n\tList full!  Save & Quit the program.");
  }
  else                                    /* Else assign record to structure */
  {
     fflush(stdin);
     BOOK[*count].recordnum = (unsigned short)(*count +1);
     inputs("\n\tEnter first name: ",    BOOK[*count].PERSON.fname, NAME);
     inputs("\tEnter last name: ",         BOOK[*count].PERSON.lname, NAME);
     inputs("\tEnter street address: ",  BOOK[*count].street, STREET);
     inputs("\tEnter city: ",            BOOK[*count].city, CITY);
     inputs("\tEnter state: ",        BOOK[*count].state, STATE);
     inputs("\tEnter zipcode: ", BOOK[*count].zipcode, ZIPCODE);
     inputs("\tEnter phone number: ", BOOK[*count].phone, PHONE);
     (*count)++;
  }
  return TRUE;
}
/*------------------------------------------------------------------------------
FUNCTION:   change
PURPOSE:   This functions changes a database record.
           The user is prompted for the record number to change.
           Then a search for the record number is conducted.
           If no match is found, the appropriate message is displayed.
           If there is a match, then the record is displayed,
           and the user is asked which element to change, or to return
           to the main menu.
------------------------------------------------------------------------------*/
static void change(struct address BOOK[], int *count)
{
  unsigned short chrec = 0;
  char ch = ' ';
  int i, quit = FALSE;
  static int find = TRUE, change = FALSE;
  char choice;
  printf("Please enter the number of the record you wish to change: ");
  scanf("%d", &chrec);
  do
  {
     for(i = 0; i < *count; i++)       /* Loop to search through all records */
     {
        if(BOOK[i].recordnum == chrec && quit != TRUE)/* If record number matches */
        {
           print_rec(i, BOOK);                      /* Display single record */
           find = TRUE;
           do
           {                        /* Ask with element user wants to change */
              printf("\n\n\tWhich record do you wish to change?");
              printf("\n\t(F)irst name\n\t(L)astname\n\t(A)ddress");
              printf("\n\t(C)ity\n\t(S)tate\n\t(Z)ipcode\n\t(P)hone\n\t(R)eturn to menu");
              printf("\n\n\tEnter your choice: ");
              fflush(stdin);
              gets(&choice);
           } while( !strchr( "FLACSZPR", toupper(choice) ) );
           switch( toupper(choice) )              /* Input and assign change */
           {
              case 'F':
                    inputs("\tEnter first name: ",      BOOK[i].PERSON.fname, NAME);
                    change = TRUE;
                    break;
              case 'L':
                    inputs("\tEnter last name: ",         BOOK[i].PERSON.lname, NAME);
                    change = TRUE;
                    break;
              case 'A':
                    inputs("\tEnter street address: ",  BOOK[i].street, STREET);
                    change = TRUE;
                    break;
              case 'C':
                    inputs("\tEnter city: ",            BOOK[i].city, CITY);
                    change = TRUE;
                    break;
              case 'S':
                    inputs("\tEnter state: ",        BOOK[i].state, STATE);
                    change = TRUE;
                    break;
              case 'Z':
                    inputs("\tEnter zip code: ", BOOK[i].zipcode, ZIPCODE);
                    change = TRUE;
                    break;
               case 'P':
                    inputs("\tEnter telephone number: ", BOOK[i].phone, PHONE);
                    change = TRUE;
                    break;
              case 'R':
                    quit = TRUE;
           }
        }
     }
  }while(quit != TRUE);
  if(change == TRUE)
  {
     printf("\nThe change was successful...");
  }
  else
  {
     if(find == FALSE)
     {
        printf("\nRecord number not found.");
     }
     printf("\nNo changes were made...");
  }
  printf("\nPress enter to return to main menu...");
  getch();
  //clrscr();
  fflush(stdin);
  //scanf("%c", &ch);
}
/*------------------------------------------------------------------------------
FUNCTION:   del
PURPOSE:   This function flags a record for deletion,
           and re-initialises the record numbers.
           The user is asked which record to delete,
           If there is a match, then confirmation is required,
           If deletion is confirmed, record is flagged.
           Appropriate messages are displayed after users options.
------------------------------------------------------------------------------*/
static void del(struct address BOOK[], int *count)
{
  unsigned short chrec = 0;
  int i, j, done = 0;
  char answer;
  printf("\n\nPlease enter the number of the record you wish to delete: ");
  fflush(stdin);
  scanf("%d", &chrec);
  for(i = 0; i < *count, done == FALSE; i++)/* Loop to search through all records */
  {
     if(BOOK[i].recordnum == chrec)              /* If record number matches */
     {
        print_rec(i, BOOK);                         /* Display single record */
        do
        {                                                    /* Confirmation */
           printf("\n\nYou have chosen to delete record number ");
           printf("%d.  Are you sure? Y or N: ", BOOK[i].recordnum);
           fflush(stdin);
           scanf("%c", &answer);
        } while( !strchr( "YN", toupper(answer) ) );
        if( toupper(answer) == 'Y')                        /* If answer is Y */
        {
           BOOK[i].recordnum = 0;                       /* Flag for deletion */
           for(j = 0; j < *count; j++)        /* Loop to include all records */
           {
              if(BOOK[j].recordnum != 0 && BOOK[j].recordnum > chrec)
              {                                     /* Update record numbers */
                 BOOK[j].recordnum -= (unsigned short)1;
              }
           }
           printf("\n\nThe record has been flagged for deletion...\nThe actual ");
           printf("deletion will occur the next time the file is saved to disk");
           done = TRUE;
        }
        else
        {
           printf("Okay, deletion has been cancelled, returning to menu...");
           done = TRUE;
        }
     }
  }
  if(done == FALSE)
  {
     printf("record not found");
  }
}
/*------------------------------------------------------------------------------
FUNCTION:   help
PURPOSE:   This function brings up a help menu for the user to explain
           the features of this program.
------------------------------------------------------------------------------*/
static void help()
{
  //char ch;
  printf("Enter the letter in brackets to activate your choice.\n");
  printf("What would you like help with?");
  switch( menu() )
  {
     case 'L':
           printf("\n----- LOADING A FILE -----\n");
           printf("This option allows you to enter the name of a file which will then be");
           printf("\nopened and read into memory.\n\n");
           printf("You can use this option more than once in order to read several files into\n");
           printf("the program, in which case the contents of each succeeding file are\n");
           printf("added to the end of the same address book already in memory.\n");
           break;
     case 'S':
           printf("\n----- SAVING A RECORD -----\n");
           printf("This option allows you to write the contents if the address book from\n");
           printf("memory to disk.\n\n");
           printf("Any records that have been flagged for deletion will not be saved to disk.\n\n");
           printf("When this option has been chosen, you will be asked if you wish to \n");
           printf("overwrite the last filename that was opened.  If you do not wish to do\n");
           printf("this, you can enter the name of a new file which will then be the\n");
           printf("destination of the updated address book.\n");
           break;
     case 'A':
           printf("\n----- ADDING A NEW RECORD -----\n");
           printf("This option allows you to enter new records which will be added to the\n");
           printf("address book in memory.\n\n");
           printf("You can enter new records either before or after file(s) have been loaded\n");
           printf("into the address book.\n\n");
           printf("You can create a new file by adding records with this option, then saving\n");
           printf("them as a new file by using the SAVE FILE option, without having to load\n");
           printf("any files.\n");
           break;
     case 'C':
           printf("\n----- CHANGING A RECORD -----\n");
           printf("Enter a record number, then you can change either name, address or both.\n\n");
           printf("The record details for the requested record is displayed on the screen\n");
           printf("and then you enter which type to change.\n\n");
           printf("All change operations affect only the address book stored in memory - that\n");
           printf("is, until the user saves the list to disk with the SAVE FILE option.\n");
           break;
     case 'D':
           printf("\n----- DELETING A RECORD -----\n");
           printf("After selecting this option, you can enter the record number you wish to\n");
           printf("delete from the address book.\n\n");
           printf("When the record number has been entered, the record details are\n");
           printf("displayed on screen and you are requested for confirmation.\n");
           printf("If you choose not not to delete, then you're returned to the main menu.\n");
           printf("If you confirm deletion, the record number is set flagged for deletion.\n");
           printf("The actual deletion occurs next time the file is saved to disk.\n");
           break;
     case 'P':
           printf("\n----- PRINTING THE RECORDS -----\n");
           printf("This option allows you to choice of sending the output to the screen, or\n");
           printf("to the printer.\n");
           break;
     case 'H':
           printf("\n----- THE HELP MENU -----\n");
           printf("This option displays a help menu.  When you enter a letter in brackets,\n");
           printf("you can recieve info on the particular option.\n");
           break;
     case 'Q':
           printf("\n----- QUITING THIS PROGRAM -----\n");
           printf("This option allows you to exit this program.\n");
           break;
     case 'O':
           printf("\n----- Sorting -----\n");
           printf("This option allows you to sort your entries.\n");
           break;
     }
  fflush(stdin);
  printf("\n\nPress enter to return to the main menu...");
  getch();
  //scanf("%c", &ch);
  //clrscr();
}
/*------------------------------------------------------------------------------
FUNCTION:   input
PURPOSE:   This function displays a prompt, and validates the response
           by length only.
           Then string copys the valid response to the pointer passed.
------------------------------------------------------------------------------*/
static void inputs(char *prompt, char *str, unsigned int max)
{
  char temp[80];
  printf(prompt);
  do
  {
     gets(temp);
     if(strlen(temp) > max)
     {
        printf("\a\n\tToo long, please re-enter: ");
     }
  } while(strlen(temp) > max);
  strcpy(str, temp);
}
/*------------------------------------------------------------------------------
FUNCTION:   load
PURPOSE:   This function loads a database into memory.
           The user is asked for a file name, which is validated.
           If this is not the first file to be loaded,
           Then a new record number is assigned to be added to the current
           database in memory.
           Otherwise, the records are copied as is.
           The process is validated, and appropriate errors display a message.
------------------------------------------------------------------------------*/
static int load(struct address BOOK[], int *count, char *fileptr, int lastfile)
{
  FILE *fp;
  static struct address TEMP;
  char ch = ' ';
  printf("\tEnter the name of the input file: ");
  scanf("%s", fileptr);
  if( (fp = fopen(fileptr, "rb") ) == NULL )   /* Open the file to read from */
  {
     fprintf(stderr, "\nFile open error on <%s>", fileptr);
  }
  else
  {
     if(lastfile == TRUE)                    /* If there are already records */
     {
        fread(&TEMP, sizeof(struct address), 1, fp);
        while(!ferror(fp) && ! feof(fp) && *count < LIST)
        {
         BOOK[*count] = TEMP;                    /* Assign new record number */
         BOOK[*count].recordnum      = (unsigned short)(*count +1);
         (*count)++;
         fread(&TEMP, sizeof(struct address), 1, fp);
        }
     }
     else
     {
                                 /* Read records from database one at a time */
                                  /* and increment number of records in list */
        fread(&BOOK[*count], sizeof(struct address), 1, fp);
        while(!ferror(fp) && ! feof(fp) && *count < LIST)
        {
           (*count)++;
           fread(&BOOK[*count], sizeof(struct address), 1, fp);
        }
     }
     if( ferror(fp) )
     {
        fprintf(stderr, "File read error has occurred.");
     }
     else if(*count >= LIST)                      /* not all records may fit */
     {
        fprintf(stderr, "\n\tList full!  Quit the program.");
     }
     else
     {
        printf("\n\tFile <%s> loaded into memory.", fileptr);
        lastfile = TRUE;
     }
     fclose(fp);
  }
  printf("\nPress enter to continue...");
  getch();
  //clrscr();
  fflush(stdin);
  //scanf("%c", &ch);
  return lastfile;
}
/*------------------------------------------------------------------------------
FUNCTION:   menu
PURPOSE:   Display menu options and validate input choices
------------------------------------------------------------------------------*/
static char menu()
{
  static char ch;
  do
  {
     printf("\n\t(L)oad a file");
     printf("\n\t(S)ave a file");
     printf("\n\t(A)dd a record");
     printf("\n\t(C)hange a record");
     printf("\n\t(D)elete a record");
     printf("\n\t(P)rint file");
     printf("\n\t(H)elp");
       printf("\n\tS(o)rt");
     printf("\n\t(Q)uit");
     printf("\n\n\tEnter your choice: ");
     fflush(stdin);
     scanf("%c", &ch);
     if( !strchr( "LSACDPOHQ", toupper(ch) )  )
     {
        printf("\nYou have entered an invalid key, please try again...");
     }
  } while( !strchr( "LSACDPOHQ", toupper(ch) )  );
  return (char)toupper(ch);
}
/*------------------------------------------------------------------------------
FUNCTION:   printlist
PURPOSE:   Prints database to screen or printer.
------------------------------------------------------------------------------*/
static void printlist(struct address BOOK[], int *count)
{
  FILE *handle;
  int i = 0, j = 0, printer = 0, counter = 0;
  //char ch;
  do
  {
     printf("\n Do you want to send output to the printer? ");
     printf("\nType 0 to print screen, 1 to print to printer: ");
     scanf("%d", &printer);
     fflush(stdin);
     if(printer == TRUE)
     {
                                                  /* Open channel to printer */
        handle = fopen("PRINTER_PORT", "wt");
#if DEBUG
        freopen(DEBUGFILE, "wt", handle);   /* Redirect the standard printer */
#endif                                                    /* stream to a file */
     }
     if(printer == FALSE)
     {
        handle = stdout;                          /* Assign handle to screen */
     }
  } while( printer != 0 && printer != 1);
                                                              /* Print title */
  fprintf(handle, "\nREC # LAST         FIRST           ADDRESS");
  fprintf(handle, "            CITY      STATE   ZIPCODE   TELEPHONE\n");
  for(j = 0; j <92; j++)
  {
     fprintf(handle, "%c", '-');
  }
  for(j = 0; j < *count; j++)                 /* Loop to include all records */
  {
     if(counter >= 20)                                     /* If end of page */
     {
        if(handle == stdout)                        /* If printing on screen */
        {
           printf("\n----- Press any key to continue -----\n");
           getch();
           fflush(stdin);
        }
        else
        {
           fputc('\f', handle);              /* Else formfeed at end of page */
        }
                                                              /* Print title */
         fprintf(handle, "\nREC # LAST         FIRST           ADDRESS");
         fprintf(handle, "            CITY      STATE   ZIPCODE   TELEPHONE\n");
        for(i = 0; i < 92; i++)
        {
           fprintf(handle, "%c", '-');
        }
        counter = 0;
     }                                                         /* Print body */
     fprintf(handle, "\n%4d  ",    BOOK[j].recordnum);
     fprintf(handle, "%-13s%-13s", BOOK[j].PERSON.lname,
                                   BOOK[j].PERSON.fname);
     fprintf(handle, "%-21s",      BOOK[j].street);
     fprintf(handle, "%-12s ",     BOOK[j].city);
     fprintf(handle, "%-5s",       BOOK[j].state);
     fprintf(handle, "  %-1s",       BOOK[j].zipcode);
     fprintf(handle, "  %s",       BOOK[j].phone);
     counter++;
  }
  if(printer == TRUE)                             /* If outputing to printer */
     {
        fputc('\f', handle);                                    /* Form feed */
        fclose(handle);                           /* Close stream to printer */
     }
  printf("\n\nReturning to menu, press enter to continue...\n");
  getch();
  //scanf("%c", &ch);
  //clrscr();
}
/*------------------------------------------------------------------------------
FUNCTION:   print_rec
PURPOSE:   Prints a single record to the screen.
------------------------------------------------------------------------------*/
static void print_rec(int i, struct address BOOK[])
{
  int j = 0;
  printf("\nREC # LAST         FIRST           ADDRESS");       /* Print title */
  printf( "            CITY      STATE   ZIPCODE   TELEPHONE\n");
  for(j = 0; j < 92; j++)
  {
     printf("%c", '-');
  }                                                            /* Print body */
  printf("\n%4d  ",    BOOK[i].recordnum);
  printf("%-13s%-13s", BOOK[i].PERSON.lname,
                       BOOK[i].PERSON.fname);
  printf("%-21s",      BOOK[i].street);
  printf("%-12s",      BOOK[i].city);
  printf("%-5s",       BOOK[i].state);
  printf("  %-1s",       BOOK[i].zipcode);
  printf("  %s",       BOOK[i].phone);
}
/*------------------------------------------------------------------------------
FUNCTION:   save
PURPOSE:   Rewrites database to disk.
------------------------------------------------------------------------------*/
static void save(struct address BOOK[], int *count, char *fileptr, int lastfile)
{
  FILE *fp;
  int i = 0, file_error = FALSE;
  char answer = 0;
                         /* If lastfile is true and there's a file in memory */
  if(lastfile == TRUE && *fileptr != '\0')
  {
     do
     {                                                       /* Confirmation */
        printf("Do you wish to overwrite the last filename opened? Y or N: ");
        fflush(stdin);
        scanf("%c", &answer);
     } while( !strchr( "YN", toupper(answer) ) );
  }
  if( toupper(answer) == 'Y')                              /* If answer is Y */
  {
     if( (fp = fopen(fileptr, "wb") ) == NULL)  /* Open the file to write to */
     {
        fprintf(stderr, "\nFile open error on <%s>", *fileptr);
        file_error = TRUE;
     }
  }
  else
  {
     printf("\n\tEnter the new file to be saved: ");
     scanf("%s", fileptr);
     if( (fp = fopen(fileptr, "wb") ) == NULL)  /* Open the file to write to */
     {
        fprintf(stderr, "\nFile open error on <%s>", *fileptr);
        file_error = TRUE;
     }
  }
  if(file_error == FALSE)
  {
     for(i = 0; i < *count; i++)                     /* Loop for all records */
     {
        if(BOOK[i].recordnum > 0)
        {
           fwrite(&BOOK[i], sizeof(struct address), 1, fp); /* Write records */
        }                                           /* to disk one at a time */
     }
     fprintf(stdout, "\nFile <%s> saved...\n", fileptr);
     fclose(fp);
  }
}
Avatar of originalrobby
originalrobby

wow, if i had the time dude i'd help ya
I suggest you post your request at
http://www.rentacoder.com

I am sure somebody will do it for you for less than $10
ASKER CERTIFIED SOLUTION
Avatar of Koma666
Koma666
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of siasd

ASKER

To Koma666:  I appreciate your efforts but, I have downloaded you addition to my program and I've tried it on several compilers and I can't get it to compile.  What compiler did you use?  SIASD
i used visual c++ 6.0
what  error did you get ?