Thread: Phonebook in C

  1. #1
    Registered User
    Join Date
    Oct 2014
    Posts
    2

    Phonebook in C

    I'm having trouble understanding how to get my phonebook to print out it's entries. If I just have one entry, it will correctly display it but if I have 2 or more, it leaves out chunks of that entry's data.
    Any help is appreciated and thanks in advance.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    
    
    
        typedef struct entry{
        char firstN[50];
        char lastN[50];
        char phoneN[50];
        }phone;//end struct
        
        void AddNew (phone * );
        void ShowBook (phone * );
        int total=0;
       
    
    
    int main(void){
        int choice=0;
        phone *phonebook = (phone*) calloc(1, sizeof(phone));
        if (phonebook == NULL){
            printf("No remaining memory, now exiting!");
            return 1;
        }
        
        
        while(choice != 3){
            printf("\nWhat would you like to do?\n\n");
            printf("1.) Add Friend\n");
            printf("2.) Show Phone Book\n");
            printf("3.) Exit\n\n");
            
            scanf("%d", &choice);
            switch(choice){
                case 1:
                    AddNew(phonebook);
                    
                    break;//end case 1
                case 2:
                    ShowBook(phonebook);
                    break;//end case 2
                case 3:
                    printf("Goodbye!");
                    free(phonebook);
                    return 0;
                    break;//end case 3
                default:
                    printf("Choice not in range. Please select a valid option.\n");
                    break;//end default
            }//end switch
        }//end while loop
    }//end main
    
    
    void AddNew (phone *phonebook){
        total++;
        char *firstname=(char *)calloc(50, sizeof(char));
        char *lastname=(char *)calloc(50, sizeof(char));
        char *phonenumber=(char *)calloc(50, sizeof(char));
        
        phone *temp = (phone*) realloc(phonebook, sizeof(phone*)*total);
        
        phonebook = temp;
        
        printf("What is your friend's first name?\n");
        scanf("%s", firstname);
        printf("What is your friend's last name?\n");
        scanf("%s", lastname);
        printf("What is your friend's number?\n");
        scanf("%s", phonenumber);
        strcpy(phonebook[total-1].firstN, firstname);
        strcpy(phonebook[total-1].lastN, lastname);
        strcpy(phonebook[total-1].phoneN, phonenumber);
    }
    
    
    void ShowBook (phone * phonebook){
        printf("Your Entries- \n");
        int x=0;
        for(x=0;x<total;x++){
        printf("%d.\t", x+1);
        printf("%s, %s\t %s\n", phonebook[x].lastN, phonebook[x].firstN, phonebook[x].phoneN);
        }
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    What would you like to do?
    
    
    1.) Add Friend
    2.) Show Phone Book
    3.) Exit
    
    
    2
    Your Entries- 
    1.    doe, jon     1234567890
    2.    flintstone, fred     9876543211
    3.    rubble, barney     9998887777
    I can't replicate your problem. Maybe you can give us the exact input you use that causes the problem, and the exact output you see that is incorrect.

    EDIT: I probably don't need actual input, but it's a good idea to provide that in the future, it makes it easier for us to help you.

    Other notes

    • Don't use magic numbers. Instead of using 50 everywhere, define some constants with sensible names. You should have at least 2: PHONE_NUM_LEN and NAME_LEN. They can both have the same value, but they should be separate. That way, if you decide you need to change one, you simply change the definition (1 line) and it's changed everywhere.
    • Don't use global variables: Global Variables Are Bad. Declare total in main and pass it to functions as needed.
    • Don't cast the return value of malloc/calloc/realloc: FAQ > Casting malloc - Cprogramming.com.
    • You calloc firstname, lastname and phonenumber in AddNew(), but never free them. This is a memory leak. You don't even need to calloc though, or need those variables at all. You can scanf directly into phonebook[total-1].firstname, etc. Then you can avoid the strcpy as well.
    • If realloc fails for whatever reason, temp will be NULL and you'll lose the original pointer for phonebook, resulting in a memory leak. You need to check if the temp pointer is NULL before you assign it back to phonebook.
    • In main, you use sizeof(phone) in your allocation, but in AddNew, you use sizeof(phone*). These are not the same and phone* is wrong. That only allocates the size of a pointer, not the whole struct. Thus, when you fill in firstname, etc for the struct, you are writing to memory you don't own. That results in undefined behavior: Question 11.33. This is likely the source of your problem.

  3. #3
    Registered User
    Join Date
    Oct 2014
    Posts
    2
    So this is what my code looks like now. I am now receiving the correct output. How would I pass my total to my functions as you suggest in your second note?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    
    
    
        typedef struct entry{
        char firstN[50];
        char lastN[50];
        char phoneN[50];
        }phone;//end struct
        
        void AddNew (phone *);
        void ShowBook (phone *);
        int total=0;
       
    
    
    int main(void){
        int choice=0;
        int total=0;
        phone *phonebook = (phone*) calloc(1, sizeof(phone));
        if (phonebook == NULL){
            printf("No remaining memory, now exiting!");
            return 1;
        }
        
        
        while(choice != 3){
            printf("\nWhat would you like to do?\n\n");
            printf("1.) Add Friend\n");
            printf("2.) Show Phone Book\n");
            printf("3.) Exit\n\n");
            
            scanf("%d", &choice);
            switch(choice){
                case 1:
                    AddNew(phonebook);
                    break;//end case 1            
                case 2:
                    ShowBook(phonebook);
                    break;//end case 2
                case 3:
                    printf("Goodbye!");
                    free(phonebook);
                    return 0;
                    break;//end case 3
                default:
                    printf("Choice not in range. Please select a valid option.\n");
                    break;//end default
            }//end switch
        }//end while loop
    }//end main
    
    
    void AddNew (phone *phonebook){
        total++;
        
        phone *temp = (phone*) realloc(phonebook, sizeof(phone)*total);
        
        phonebook = temp;
        
        if (temp==NULL){
            printf("An error has occoured.");
        }
        else{
        printf("What is your friend's first name?\n");
        scanf("%s", phonebook[total-1].firstN);
        printf("What is your friend's last name?\n");
        scanf("%s", phonebook[total-1].lastN);
        printf("What is your friend's number?\n");
        scanf("%s", phonebook[total-1].phoneN);
    }
    }
    void ShowBook (phone * phonebook){
        if (total==0){
            printf("You have no entries!");
        }
        else{
        printf("Your Entries- \n");
        int x=0;
        for(x=0;x<total;x++){
        printf("%d.\t", x+1);
        printf("%s, %s\t %s\n", phonebook[x].lastN, phonebook[x].firstN, phonebook[x].phoneN);
        }}
    }

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You failed to implement several of my suggestions. Fix these first:
    1. Don't use magic numbers. Define some constants.
    2. Don't cast malloc/calloc/realloc.
    3. Remove the global variable total.

    Also, please make sure your posts and your actual code are properly indented/formatted. Note, for example, how the if/else blocks in AddNew and ShowBook are not properly formatted/indented. Newbies often seriously underestimate the value of clear, easy to read code. If it's easy to read, it's harder to make a mistake and easier to find and fix when you do.

    Note, total is not a great name, something like num_phonebook_entries is much more descriptive, never sacrifice clarity to save a few keystrokes. Also, AddNew is too generic; add a new what? Try AddPhonebookEntry. Consistency is nice too, so maybe ShowPhonebook would be better than "ShowBook".

    As for the fuctions: your current code suggests you can declare and call a function with one parameter, what do you not understand about a function that takes two arguments?

    AddPhonebookEntry will need to change the value of phonebook and num_phonebook_entries, so that it is reflected in main. Currently, you are only modifying the local copy of phonebook (since C is pass by value), so if realloc needs to move the pointer, the phonebook in main wont have the new value -- another memory leak. If you don't know how to do this (have a function change the value of a parameter so it's reflected in the caller), I suggest you read up about functions in your textbook and class notes, and some tutorials online. If you need more specific search terms, you can try "C pass by reference" or "C function ouput parameter".

    Once you do that, give it your best shot and if you're still stuck, post back here.

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    88
    How does phonebook in main get updated by AddNew ?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Phonebook Homework
    By Megan Ridenour in forum C Programming
    Replies: 3
    Last Post: 07-15-2013, 09:18 AM
  2. PHONEBOOK in c
    By chie22 in forum C Programming
    Replies: 6
    Last Post: 10-17-2011, 03:26 PM
  3. phonebook help
    By noob2c in forum C Programming
    Replies: 5
    Last Post: 04-19-2003, 01:51 PM
  4. phonebook error
    By cguy in forum C Programming
    Replies: 2
    Last Post: 01-30-2003, 01:08 AM
  5. phonebook
    By jk81 in forum C Programming
    Replies: 6
    Last Post: 09-25-2002, 04:41 AM

Tags for this Thread