?
Solved

ADDING A SORT FUNCTION

Posted on 2003-03-07
7
Medium Priority
?
246 Views
Last Modified: 2010-04-17
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);
   }
}
0
Comment
Question by:siasd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 5

Expert Comment

by:Koma666
ID: 8089208
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);
  }
}
0
 

Expert Comment

by:originalrobby
ID: 8090826
wow, if i had the time dude i'd help ya
0
 
LVL 27

Expert Comment

by:Dabas
ID: 8091036
I suggest you post your request at
http://www.rentacoder.com

I am sure somebody will do it for you for less than $10
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Accepted Solution

by:
Koma666 earned 500 total points
ID: 8102656
why should he do that, i´ve allready posted the version with order function :-) just look  at the first comment
0
 

Author Comment

by:siasd
ID: 8127591
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
0
 
LVL 5

Expert Comment

by:Koma666
ID: 8127607
i used visual c++ 6.0
0
 
LVL 5

Expert Comment

by:Koma666
ID: 8127615
what  error did you get ?
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
In the absence of a fully-fledged GPO Management product like AGPM, the script in this article will provide you with a simple way to watch the domain (or a select OU) for GPOs changes and automatically take backups when policies are added, removed o…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Six Sigma Control Plans
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question