1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

simple user directory program

Discussion in 'C' started by hobbyist, May 5, 2012.

  1. hobbyist

    hobbyist New Member

    Joined:
    Jan 7, 2012
    Messages:
    141
    Likes Received:
    0
    Trophy Points:
    0
    Here's a bit of sample code for adding, searching records in a binary file. If anyone sees anything problematic, please point it out. Thanks. :)

    main.h
    Code:
    /*******************/
    /*   macro guard  */
    /*******************/ 
    
    #ifndef __MAINHEADER__
    #define __MAINHEADER__
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /********************/
    /* UDTs; constants; */
    /********************/
    
    typedef struct {
    
       char name[40];
       char phone1[16];
       char phone2[16];
       char addr[120];
       char city[100];   
       char zipc[10];
    
    } contact;
    
    
    /***********************/
    /* function prototypes */
    /***********************/
    
    void showMenu(void);
    void showNames(FILE *);
    int addListing(FILE *);
    void searchList(FILE *);
    int deleteListing(FILE *);
    
    #endif
    functions.c
    Code:
    #include "main.h"
    
    void showMenu(void) {
    
       printf("1) Add listing\n2) Delete listing\n3) Show listing\n4) Search listing\n5) Quit\n\n--> ");
    }
    
    void showNames(FILE *f) {
    
       /* nothing fancy... just print names of
          entries in file */
    
       char *p;
       contact *tmp = malloc(sizeof(*tmp));
       /* create temporary variable */   
       
       if(tmp) {
    
          rewind(f);                   /* clear any eof bit and     */
          fseek(f, 0, SEEK_END);  /* find out how many entries exist */
    
          if((ftell(f) / sizeof(contact)) > 0) {
    
             rewind(f);
             fseek(f, 0, SEEK_SET);
    
             while(fread(tmp, sizeof(contact), 1, f) == 1) {
                if((p = strchr(tmp->name, '\n')) != NULL)
                   *p = '\0';
    
                puts(tmp->name);
             }
    
          } else
              puts("\nthere are no entries to list\n");
    
          free(tmp);   /* release memory */
          tmp = NULL;
       } 
    } 
    
    int addListing(FILE *f) {
    
       contact *tmp = malloc(sizeof(*tmp));
       int ret = 0;   
       
       if(tmp) {
    
          system("cls"); /* non-standard function; comment out if needed */
    
          /* ask for data; side effect of fgets is 
              it stores the newline char.  remove it
              here or during any output */
       
          printf("Enter name: ");
          fgets(tmp->name, sizeof(tmp->name), stdin);
    
          printf("Enter address: ");
          fgets(tmp->addr, sizeof(tmp->addr), stdin);
    
          printf("Enter city, state: ");
          fgets(tmp->city, sizeof(tmp->city), stdin);
    
          printf("Enter phone1: ");
          fgets(tmp->phone1, sizeof(tmp->phone1), stdin);
    
          printf("Enter phone2: ");
          fgets(tmp->phone2, sizeof(tmp->phone2), stdin);
    
          printf("Enter zipcode: ");
          fgets(tmp->zipc, sizeof(tmp->zipc), stdin);
    
          ret = fwrite(tmp, sizeof(contact), 1, f);
          free(tmp);
       }
       
       return ret;
    } 
    
    void searchList(FILE *f) {
    
       char input[3] = { 0 }, *p;
       
       system("cls"); /* non-standard function */
    
       do {      
    
          /* loop while option isn't 1-4 */
    	     
          printf("1) By name\n2) By city\n3) By state\n4) Go back\n--> ");
          fgets(input, sizeof input, stdin);
    	  
          if((p = strchr(input, '\n')) == NULL)
             while(getchar() != '\n'){}
    
       } while(input[0] < '1' && input[0] > '4');
       
       if(input[0] != '4') {
       
          char *sstr = malloc(200);
          contact *tmp = malloc(sizeof(*tmp));
    	  
          if(sstr && tmp) {
    	  
             printf("\nQuery: ");
             fgets(sstr, 200, stdin);
    		 
             if((p = strchr(sstr, '\n')) != NULL)
                *p = '\0';         
    
             rewind(f);
             fseek(f, 0, SEEK_SET);
    
             /* strstr can be used to find partial matches in
                 data fields; however, it's case-sensitive
    			
                 loop through all entries to see if they
                 "match" query */
    
             while(fread(tmp, sizeof(contact), 1, f) == 1) {
    
                switch(input[0]) {
    
                   case '1' : if(strstr(tmp->name, sstr) != NULL)
                                    puts(tmp->name);
                                 break;
                   case '2' :
                   case '3' : if(strstr(tmp->city, sstr) != NULL) {
                                   puts(tmp->name);
                                   puts(tmp->city);
                                 }
                                 break;
                }
             }
    		 
             free(sstr);
             free(tmp);
          } else 
             puts("\nerror with request\n");
       }
    }
    
    int deleteListing(FILE *f) {
    
       /* deleting a record is a chore; it requires either loading
          all records in memory and re-writing the data file with
          valid records or perhaps creating a temp file, writing only
          valid records, deleting the data file, and then
          renaming the temp file as the data file.
    
          for now, just set the name field to "deleted"
    
          code to do:
    	  
    	     prompt user to identify record to be deleted, find that
    	     record, edit the name field, call it a day
       */
       
       puts("\nfunction not implemented\n");
       return 0;
    }
    main.c
    Code:
    #include "main.h"
    
    const char *fname = "contact.dat";
    
    int main(void) {
    
       /* note: program overwrites data file each time it's run;
                bin files may run into issues with padding and/or
                differences in sizeof POD types when moving from
                machine to machine */
    
       FILE *fp = fopen(fname, "wb+");
       char input[3] = { 0 }, *p;   
    
       if(fp) {
    
          for(; ;) {
    	     
             showMenu();
             fgets(input, sizeof input, stdin);
    
             if((p = strchr(input, '\n')) == NULL)
                while(getchar() != '\n'){}
    
             if(input[0] == '5') break; 
    
             switch(input[0]) {
    
    	        case '1' : printf("\n%s\n\n", addListing(fp) == 1 ? "added entry" : "file error"); break;
                    case '2' : deleteListing(fp); break;
                    case '3' : showNames(fp);     break;
                    case '4' : searchList(fp);    break;
                    default  : printf("\ninvalid command %s\n", input);
             }
     
          }
    
          fclose(fp);
       }
    
       puts("\ndone...\n");
       return 0;
    }
     

Share This Page