Thread: Phone book program errors (troubleshooting help)

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    8

    Phone book program errors (troubleshooting help)

    I've been messing with this program for days now and I just can't get the features to work properly. When I try to delete entries it locks up and though I can add one person, when I attempt to add a second it locks up. I'm thinking the problem is related to memory and/or pointers, though I'm really not sure. I'd appreciate it if anyone could help me troubleshoot this.

    This was written in Bloodshed and the program requirements are:
    *User can enter as many entries as desired
    *Use an array of structures to hold contact info and create functions to add, delete and print entries.
    *Do not display invalid or NULL entries; you can assume all people have unique names.
    *Allocate and free memory as necessary

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //Function prototypes
    void Add();
    void Delete();
    void Display();
    
    //Structure for Phonebook list
    typedef struct PhoneBookList {
            
            const char *FirstName;
            const char *LastName;
            const char *PhoneNumber;
            
    } list;
    
    //Structure for delete
    typedef struct DeleteEntry {
            
            const char *FirstName;
            const char *LastName;
            
    } take;
    
    
    //Pointers to structures
    list *lt;
    take *tk ;
    
    //Global variables
    int count = 0;
    int delCount = 0;
    
    main() 
    { 
           //Variable declarations
           int iSelection;
           
           do {    //Print menu to screen, ask user for selection
              printf("\n\nPhone Book:\n\n");
              printf("1) Add friend\n");
              printf("2) Delete friend\n");
              printf("3) Display phone book\n");
              printf("4) Exit\n");
              printf("What do you want to do? ");
            
              scanf("%d", &iSelection);
            
              switch (iSelection) {
                           
                           case 1:  //Add entry
                                Add();  
                                break;
                           
                           case 2:  //Delete entry
                                Delete();
                                break;
                                
                           case 3:  //Display all entries
                                Display();
                                break;
                                
                           case 4: //Break loop and close program
                                break;
                           
                           default:  //User entered an invalid number
                                   printf("\nYou entered an invalid selection.  Try again.\n\n\n");
                                   system("pause");
                           
                           } //End Switch
                           
              } while (iSelection != 4);  //End Do While loop
              
              //Return used memory
              tk = NULL;
              lt = NULL;
              free(tk);
              free(lt);
              
    } //End Main
    
    //Function definitions
    
    //Add an entry
    void Add()
    {
        if (count == 0) 
         {
               lt = (list *) malloc ((count*200) + 30);
         }
         else
         {
               lt = (list *) realloc (lt, (count*1) + 1);
         }
        
        if (lt == NULL)
        {
               printf("You cannot add more memory");
        }
        else
        {
               lt[count].FirstName;
               lt[count].LastName;
               lt[count].PhoneNumber = (char*) malloc(sizeof(char)*200);
               printf("\nEnter their First Name: ");
               scanf("%s", lt[count].FirstName);
               printf("\nEnter their Last Name: ");
               scanf("%s", lt[count].LastName);
               printf("\nEnter their Phone Number (no spaces or dashes): ");
               scanf("%d", &lt[count].PhoneNumber);
               
               printf("\nContact added");
               
        }
        count++;
        system("pause");
    }
    
    //Delete an entry
    void Delete()
    {
         int i;
         int q = 0;
         char *userName;
         
         if (delCount == 0) 
         {
                   tk = (take *) malloc ((delCount*200) + 200);
         }
         else
         {
                   tk = (take *) realloc (tk, (delCount*1) + 1);
         }
         
         if (tk == NULL)
         {
                printf("This cannot be deleted (out of memory");
         }
         else
         {
                tk[delCount].FirstName = (char *) malloc(sizeof(char)*20);
                tk[delCount].LastName = (char *) malloc(sizeof(char)*20);
                printf("\nEnter their First Name: ");
                scanf("%s", tk[delCount].FirstName);
                printf("\nEnter their Last Name: ");
                scanf("%s", tk[delCount].LastName);
         }
           
         for (i = 0; i < count; i++)
         {
             if (lt[i].FirstName == NULL || lt[i].LastName == NULL) continue;
             if (strcmp(lt[i].FirstName, tk[delCount].FirstName) == 0 || strcmp(lt[i].LastName, tk[delCount].LastName) == 0)
             {
                printf("\n%s %s has been deleted", lt[i].FirstName, lt[i].LastName);
                lt[i].FirstName = NULL;
                lt[i].LastName = NULL;
                q = 1;
                break;
             }
                                         
             if (q != 1)
             {
             printf("\nThis person is not in the Phonebook");
             }
             
         } //End for loop  
         delCount++;
         system("pause");
    }//End function
    
    //Display all phonebook entries
    void Display()
    {
         int i;
         
         printf("\nYour contacts:\n");
         
         for (i = 0; i < count; i++)
         {
             if (lt[i].FirstName != NULL || lt[i].LastName != NULL)
             {
                                 printf("\n%s %s: %d\n", lt[i].FirstName, lt[i].LastName, lt[i].PhoneNumber);
             }
         }//End for loop
         
         system("pause");
    }//End function

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have a lot of things to clean up first. If you turn up the warnings when you compile, you should get something like this:
    Code:
    $ gcc -Wall phone.cphone.c:37: warning: return type defaults to ‘int’
    phone.c: In function ‘Add’:
    phone.c:104: warning: statement with no effect
    phone.c:105: warning: statement with no effect
    phone.c:108: warning: writing into constant object (argument 2)
    phone.c:110: warning: writing into constant object (argument 2)
    phone.c:112: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘const char **’
    phone.c: In function ‘Delete’:
    phone.c:146: warning: writing into constant object (argument 2)
    phone.c:148: warning: writing into constant object (argument 2)
    phone.c:126: warning: unused variable ‘userName’
    phone.c: In function ‘Display’:
    phone.c:184: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘const char *’
    phone.c: In function ‘main’:
    phone.c:82: warning: control reaches end of non-void function
    Line 37: It's int main(void). Read this link.
    Line 82: main is supposed to return an int, so do that. return 0; is typical for success.
    Line 104 and 105: Those lines don't do anything. They don't initialize or clear anything, or allocate space.
    Line 108, 110, 146 and 148: You declared FirstName and LastName to point to const data, so you can't write to it. Drop the 'const'.
    Line 112 and 184: PhoneNumber is a char *, %d is for reading in integers. Read up on the scanf documentation.

    Start fixing those, when you're done, post your new code.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    8
    Usually Bloodshed will refuse run the program and indicate where the errors are. I wonder why those aren't showing up for me.

    Lines 104-105 are almost identical to what I did in the Delete function, except lt became tk. I'm not sure why it does nothing at all. And when I take it away I can't add even one entry.

    Anyway here's my code with the fixes, still having the same problems though.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //Function prototypes
    void Add();
    void Delete();
    void Display();
    
    //Structure for Phonebook list
    typedef struct PhoneBookList {
            
            char *FirstName;
            char *LastName;
            char *PhoneNumber;
            
    } list;
    
    //Structure for delete
    typedef struct DeleteEntry {
            
            char *FirstName;
            char *LastName;
            
    } take;
    
    
    //Pointers to structures
    list *lt;
    take *tk ;
    
    //Global variables
    int count = 0;
    int delCount = 0;
    
    int main(void) 
    { 
           //Variable declarations
           int iSelection;
           
           do {    //Print menu to screen, ask user for selection
              printf("\n\nPhone Book:\n\n");
              printf("1) Add friend\n");
              printf("2) Delete friend\n");
              printf("3) Display phone book\n");
              printf("4) Exit\n");
              printf("What do you want to do? ");
            
              scanf("%d", &iSelection);
            
              switch (iSelection) {
                           
                           case 1:  //Add entry
                                Add();  
                                break;
                           
                           case 2:  //Delete entry
                                Delete();
                                break;
                                
                           case 3:  //Display all entries
                                Display();
                                break;
                                
                           case 4: //Break loop and close program
                                break;
                           
                           default:  //User entered an invalid number
                                   printf("\nYou entered an invalid selection.  Try again.\n\n\n");
                                   system("pause");
                           
                           } //End Switch
                           
              } while (iSelection != 4);  //End Do While loop
              
              //Return used memory
              tk = NULL;
              lt = NULL;
              free(tk);
              free(lt);
              
              return 0;
              
    } //End Main
    
    //Function definitions
    
    //Add an entry
    void Add()
    {
        /*if (count == 0) 
         {
               lt = (list *) malloc ((count*200) + 30);
         }
         else
         {
               lt = (list *) realloc (lt, (count*1) + 1);
         }
        
        if (lt == NULL)
        {
               printf("You cannot add more memory");
        }
        else*/
        {
               lt[count].FirstName;
               lt[count].LastName;
               lt[count].PhoneNumber = (char*) malloc(sizeof(char)*200);
               printf("\nEnter their First Name: ");
               scanf("%s", lt[count].FirstName);
               printf("\nEnter their Last Name: ");
               scanf("%s", lt[count].LastName);
               printf("\nEnter their Phone Number (no spaces or dashes): ");
               scanf("%s", lt[count].PhoneNumber);
               
               printf("\nContact added");
               
        }
        count++;
        system("pause");
    }
    
    //Delete an entry
    void Delete()
    {
         int i;
         int q = 0;
         char *userName;
         
         if (delCount == 0) 
         {
                   tk = (take *) malloc ((delCount*200) + 200);
         }
         else
         {
                   tk = (take *) realloc (tk, (delCount*1) + 1);
         }
         
         if (tk == NULL)
         {
                printf("This cannot be deleted (out of memory");
         }
         else
         {
                tk[delCount].FirstName = (char *) malloc(sizeof(char)*20);
                tk[delCount].LastName = (char *) malloc(sizeof(char)*20);
                printf("\nEnter their First Name: ");
                scanf("%s", tk[delCount].FirstName);
                printf("\nEnter their Last Name: ");
                scanf("%s", tk[delCount].LastName);
         }
           
         for (i = 0; i < count; i++)
         {
             if (lt[i].FirstName == NULL || lt[i].LastName == NULL) continue;
             if (strcmp(lt[i].FirstName, tk[delCount].FirstName) == 0 || strcmp(lt[i].LastName, tk[delCount].LastName) == 0)
             {
                printf("\n%s %s has been deleted", lt[i].FirstName, lt[i].LastName);
                lt[i].FirstName = NULL;
                lt[i].LastName = NULL;
                q = 1;
                break;
             }
                                         
             if (q != 1)
             {
             printf("\nThis person is not in the Phonebook");
             }
             
         } //End for loop  
         delCount++;
         system("pause");
    }//End function
    
    //Display all phonebook entries
    void Display()
    {
         int i;
         
         printf("\nYour contacts:\n");
         
         for (i = 0; i < count; i++)
         {
             if (lt[i].FirstName != NULL || lt[i].LastName != NULL)
             {
                                 printf("\n%s %s: %s\n", lt[i].FirstName, lt[i].LastName, lt[i].PhoneNumber);
             }
         }//End for loop
         
         system("pause");
    }//End function

  4. #4
    Here we go again...
    Join Date
    Sep 2011
    Location
    San Diego
    Posts
    102
    Is this what you were trying to do?

    if count equals zero, add malloc equals 30.

    Code:
    void Add() 
    {
    if (count == 0) {
    lt = (list *) malloc ((count*200) + 30); //0*200=0, 0+30 = 30
    }
    if count equals zero, del malloc equals 200.

    Code:
    void Delete()
    {
         int i;
         int q = 0;
         char *userName;
          
         if (delCount == 0) 
         {
                   tk = (take *) malloc ((delCount*200) + 200); //0*200=0, 0+200 = 200
         }

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The difference between lines 104/105 (106/107 in your new code) and those in the Delete() function is that in Delete(), you assign the result of malloc to FirstName and LastName. You don't do anything with the two lines in Add().

    You have some serious issues:
    • Global Variables Are Bad. Declare them in main and pass them to your functions.
    • Stop using magic numbers. Why are there 200's and 30's all over your code. #define some proper constants.
    • Don't cast the return value of malloc, read this link.
    • Your malloc/realloc calls are all broken. A common idiom is foo = malloc(number_of_foo_objects * sizeof(*foo));.
    • If you are using realloc, you need to use a temporary pointer. Store the return value of realloc in the temp pointer, check if it's NULL and if not, reassign. You have a potential memory leak otherwise.
    • If something is a fixed size, like a phone number, don't use malloc, make it an array of char. If you must use malloc, use a reasonable size (who has a 200 digit phone number?!?!)
    • You need to call free(lt) and free(tk) before setting them to NULL.
    • I have absolutely no idea why you keep an array of deleted entries. What is tk actually used for?


    You need to not write so much code at once. Write 5-10 lines, then test, 5-10 more lines, then test again, etc. Working in small chunks like that makes it easy to find and fix bugs. Test Display with a static array of phone book entries. Once Display is working, start on Add. Use Display to test the results of Add, making sure every entry you add can be properly displayed. Once Add is complete, you can start on Delete. Delete an entry and Display the list again, making sure it's really gone.

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    8
    Thanks for the help guys, I managed to get it working.

    I'm taking Intro to Programming as an elective, it has nothing to do with my major or minor. I don't know wtf I was thinking. I'm spending more time on this stuff than all my upper level classes combined. 100 level course my ass, pfff....

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Random8 View Post
    Thanks for the help guys, I managed to get it working.

    I'm taking Intro to Programming as an elective, it has nothing to do with my major or minor. I don't know wtf I was thinking. I'm spending more time on this stuff than all my upper level classes combined. 100 level course my ass, pfff....
    Then, in all due respect... if that's how you feel, you need to drop the course.

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    8
    Too late for that. Everything was manageable for the first 6 lab assignments. But things are starting to really ramp up now. And that would happen AFTER the deadline to drop for a W, of course.

    I can probably still manage a B. Maybe and A if the Professor gives a curve. At least now I know programming is just not for me.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok then... if you can't drop the course... *start paying attention in class*... this is not a difficult assignment...

    Work it in steps... The big requirement here is a struct that describes a phone book entry; you already have that as a type def. Next the assignment says to create an array of structs... you should do that before you try to do anything else. Then you have the necessary functions... add, remove, display... work on getting it to display the whole array first "Show list" so that you can see that your array is being correctly instantiated. Then it's time to add an entry... that means using malloc to allocate memory and then filling in the variables... get that working, make sure it displays correctly, then move to the next step... and so on....

    One last hint...

    Here's a proper struct for the job...
    Code:
    //Structure for Phonebook list 
    typedef struct PhoneBookList {                   
       char FirstName[20];
       char LastName[20];
       char PhoneNumber[16];  
       } list;
    Now ... You probably want to create an array of pointers to your phonebooklist structs...
    Last edited by CommonTater; 10-13-2011 at 06:09 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. tell me the errors of this simple phone book ?
    By blogchama in forum C Programming
    Replies: 5
    Last Post: 01-16-2010, 05:42 AM
  2. Phone book
    By Nightmaresiege in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2008, 05:12 PM
  3. a phone book program
    By mackieinva in forum C Programming
    Replies: 2
    Last Post: 09-19-2007, 06:31 AM
  4. Phone Book
    By FerrariF12000 in forum C Programming
    Replies: 7
    Last Post: 12-10-2003, 12:07 AM
  5. Obscure errors, troubleshooting, anyone?
    By Golbez in forum Game Programming
    Replies: 5
    Last Post: 11-02-2002, 11:29 PM