Thread: Help me in C array for phonebook program

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

    Help me in C array for phonebook program

    I'm revising a small program, I have successfully made this small program into a larger one, but I still need two functions.

    1. have an EDIT option
    2. return multiple records upon searching.

    I am so done in C 4 years ago, I'm just helping a friend of mine.


    Code:
    
    
    
    #include <stdio.h>
    
    
    
    
    #define CAPACITY 100
    
    
    /* User commands */
    
    
    #define ADD 'a'
    #define FIND   'f'
    #define LIST   'l'
    #define QUIT   'q'
    
    
    #define NAME_LEN 80
    #define NUMBER_LEN 40
    
    
    /* In memory representation of an entry in the phonebook. */
    
    
    typedef struct {
      char name[ NAME_LEN ];
      char number[ NUMBER_LEN ];
    } phone_record;
    
    
    /* Procedures in phonebook.c */
    
    
    char get_command( void );
    phone_record *get_record( void );
    void add_record( phone_record *new_record );
    void list_phonebook( void );
    int find_name( char *name );
    
    
    int num_entries;           // Number of entries currently in the phone book
    phone_record **phonebook;  // Where the names are stored
    
    
    int main( int argc, char **argv ) {
      char ch;
      char name[ NAME_LEN ];
      char confirm[ 10 ];
      phone_record *rec;
      int loc;
    
    
      // Create an empty phonebook
      phonebook = (phone_record **)malloc( sizeof( phone_record *) * CAPACITY );
      num_entries = 0;
    
    
      // Read commands until the user gets tired
      while ( ( ch = get_command() ) != QUIT ) {
        switch( ch ) {
          case ADD:
            // Get new info
            rec = get_record();
    
    
              add_record( rec );
            
            break;
    
    
          case FIND:
            // Name to find
            printf( "Name:  " );
            scanf( "%s", name );
    
    
            // Look for the name
            if ( ( loc = find_name( name ) ) != -1 ) {
              printf( "Number:  %s\n", phonebook[ loc ]->number );
            }
            else {
              printf( "That name is not in the phonebook\n" );
            }
            break;
    
    
          case LIST:
            // List the phonebook
            list_phonebook();
            break;
        }
      }
    }
    
    
    /* 
     * Read and return a command from the keyboard. 
     */
    char get_command() {
      char line[ 80 ];
    
    
      do {
        // Get input
        printf( "pb> " );
    
    
        // scanf returns -1 when it encoutners EOF - pretend we saw quit
        if ( scanf( "%s", line ) == -1 ) {
          line[ 0 ] = QUIT;
          printf( "\n" );  // Add new line so terminal looks nice
        }
      
        // Verify input (lightly)
        switch( line[ 0 ] ) {
          case ADD:
          case FIND:
          case LIST:
          case QUIT:
            break;
          default:
            printf( "Unrecognized command\n" );
            line[ 0 ] = 0;
        }
      } while ( line[ 0 ] == 0 );
    
    
      return line[ 0 ];
    }
    
    
    /*
     * Add a new record to the phonebook.
     */
    void add_record( phone_record *new_record ) {
      int cur;
    
    
      // Make sure there is room
      if ( num_entries == CAPACITY ) {
        printf( "Sorry phonebook is full\n" );
      }
      else {
        // Insertion sort.  Start at bottom and copy elements down one until
        // you find the first one less than what we are adding or we hit the
        // top of the phonebook
        for ( cur = num_entries; 
              cur > 0 && strcmp( phonebook[ cur - 1 ]->name, new_record->name ) > 0;
              cur = cur - 1 ) {
    
    
          phonebook[ cur ] = phonebook[ cur - 1 ];
        }
    
    
        // Add the entry in the open slot
        phonebook[ cur ] = new_record;
        num_entries = num_entries + 1;
      }
    }
    
    
    /*
     * List the entries in the phonebook.
     */
    void list_phonebook() {
      int i;
    
    
      if ( num_entries != 0 ) {
        printf( "Name\t\tNumber\n" );
        printf( "----\t\t------\n" );
    
    
        for ( i = 0; i < num_entries; i = i + 1 ) {
          printf( "%s\t\t%s\n", phonebook[ i ]->name, phonebook[ i ]->number );
        }
      }
      else {
        printf( "There are no entries in the phonebook\n" );
      }
    }
    
    
    
    
    /*
     * Find a name in the phonebook.  -1 means it is not there.
     */
    int find_name( char *name ) {
      int pos = -1;
      int i;
    
    
      for ( i = 0; pos == -1 && i < num_entries; i = i + 1 ) {
        if ( strcmp( name, phonebook[ i ]->name ) == 0 ) pos = i;
      }  
    
    
      return pos;
    }
    
    
    /*
     * Read and return a phone record from the keyboard.
     */
    phone_record *get_record() {
      phone_record *rec;
      char *name;
      char *number;
    
    
      // Allocate storage for the phone record.  Since we want the record
      // to live after the function returns we need to use malloc
      rec = (phone_record *)malloc( sizeof( phone_record ) );
    
    
      // Get the data
      printf( "Name:  " );
      scanf( "%s", rec->name );
    
    
      printf( "Phone:  " );
      scanf( "%s", rec->number );
    
    
      return rec;
    }




    you might want to run to compile and run it.
    in the function:
    Code:
    int find_name( char *name ) {
      int pos = -1;
      int i;
    
      for ( i = 0; pos == -1 && i < num_entries; i = i + 1 ) {
        if ( strcmp( name, phonebook[ i ]->name ) == 0 ) pos = i;
      }  
    
      return pos;
    }
    it only returns 1 integer to this case:

    Code:
    if
    Code:
     ( ( loc = find_name( name ) ) != -1 ) {
      printf( "Number:  %s\n", phonebook[ loc ]->number );
    }

    Please help. I'm thinking that the method find_name should return an array instead, but I don't know how to implement that. Thanks

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I didn't try compiling the code, but a few notes after a quick perusal:

    - You don't include stdlib.h for malloc()
    - You don't include string.h for the string functions
    - You shouldn't use global variables -> Global Variables Are Bad
    - You shouldn't cast "malloc()" -> FAQ > Casting malloc - Cprogramming.com


    In addition, using "scanf()" to read a string is probably not the best choice for a phone book. "scanf()" (used as you have it) will only read a single word (up to the first whitespace). For reading a full line of text, see here -> FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com

    Please help. I'm thinking that the method find_name should return an array instead, but I don't know how to implement that. Thanks
    You can't return an array from a function.

    My advice would be to redo your program using a dynamic data structure. You're actually half way to implementing a linked list for your phone book - perhaps you should look into fully implementing your phone book as a linked list. This way, instead of allocating a fixed amount of memory, you can allocated as needed.

    If you do this, then you could simply create a second list for your "find_name()" function, and build a second list that contains only the data for the names of interest.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I would suggest you see about increasing your compiler warning level, your compiler should be able to tell you about some of the problems.


    main.c||In function ‘main’:|
    main.c|54|error: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]|
    main.c|54|warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]|
    main.c|60|warning: switch missing default case [-Wswitch-default]|
    main.c|48|warning: unused variable ‘confirm’ [-Wunused-variable]|
    main.c|45|warning: unused parameter ‘argc’ [-Wunused-parameter]|
    main.c|45|warning: unused parameter ‘argv’ [-Wunused-parameter]|
    main.c||In function ‘add_record’:|
    main.c|148|error: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]|
    main.c||In function ‘get_record’:|
    main.c|215|warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]|
    main.c|210|warning: unused variable ‘number’ [-Wunused-variable]|
    main.c|209|warning: unused variable ‘name’ [-Wunused-variable]|
    ||=== Build finished: 2 errors, 8 warnings (0 minutes, 0 seconds) ===|
    You seem to be missing at least one required header file, and you should also stop casting the return value from malloc.

    Jim

  4. #4
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by Matticus View Post
    I didn't try compiling the code, but a few notes after a quick perusal:

    - You don't include stdlib.h for malloc()
    - You don't include string.h for the string functions
    - You shouldn't use global variables -> Global Variables Are Bad
    - You shouldn't cast "malloc()" -> FAQ > Casting malloc - Cprogramming.com


    In addition, using "scanf()" to read a string is probably not the best choice for a phone book. "scanf()" (used as you have it) will only read a single word (up to the first whitespace). For reading a full line of text, see here -> FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com



    You can't return an array from a function.

    My advice would be to redo your program using a dynamic data structure. You're actually half way to implementing a linked list for your phone book - perhaps you should look into fully implementing your phone book as a linked list. This way, instead of allocating a fixed amount of memory, you can allocated as needed.

    If you do this, then you could simply create a second list for your "find_name()" function, and build a second list that contains only the data for the names of interest.
    Hey sir, thank you for the quick response and for sir Jim as well.

    Yeah, they say casting malloc is bad, but hey, it is working.
    I'm afraid I don't have much time to redo my whole program. I'm about to finish it, ughh, don't discourage me I only need to list down all the details using that find_name and lastly, add an EDIT function, I believe this is much easier.

    JIM - I use C-Free compiler, it works, even with stdio.h header alone! as well as in Dev-C++. But anyway, I will include stdlib and string.


    Please provide more help, I really need to finish it. @_@

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Yeah, they say casting malloc is bad, but hey, it is working.
    Did you read the link I posted?

    I'm afraid I don't have much time to redo my whole program. I'm about to finish it, ughh, don't discourage me I only need to list down all the details using that find_name and lastly, add an EDIT function, I believe this is much easier.
    Alright, how about this for a quick fix. Since you're doing nothing with the found record in "main()" except for printing it, why not just have your "find_name()" function print each entry as it is found throughout the list? This will require only minor modifications.

    As for an editing function, just create a new function that accepts a single record, prompts for the new information, and updates the appropriate fields in the supplied record.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Oh, and by the way, and cross-posting is considered very poor etiquette. C phonebook program return array - Stack Overflow

  7. #7
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by Matticus View Post
    Did you read the link I posted?



    Alright, how about this for a quick fix. Since you're doing nothing with the found record in "main()" except for printing it, why not just have your "find_name()" function print each entry as it is found throughout the list? This will require only minor modifications.

    As for an editing function, just create a new function that accepts a single record, prompts for the new information, and updates the appropriate fields in the supplied record.
    I have this function for listing all the entries.
    Code:
    void list_phonebook() {
      int i;
    
    
      if ( num_entries != 0 ) {
        printf( "Name\t\tNumber\n" );
        printf( "----\t\t------\n" );
    
    
        for ( i = 0; i < num_entries; i = i + 1 ) {
          printf( "%s\t\t%s\n", phonebook[ i ]->name, phonebook[ i ]->number );
        }
      }
      else {
        printf( "There are no entries in the phonebook\n" );
      }
    }
    I can somehow get your idea sir. The code that I have is just for printing all the info, but I need to filter it using the name given by the user.


    Your method is simple sir, I can do it. Unfortunately there is a requirement:

    EDIT ENTRY IN ASEAN PHONEBOOK
    Ask the user for the student number. If it does not exist, alert an error. Otherwise, editing should proceed, like the one below, the “edit menu”:
    Enter student number: 2004-56
    Here is the existing information about 2004-56:
    Sukarno Lee is a Doctor. His number is 63-2-4567890
    Which of the following information do you wish to change?
    [1] Student number [2] Surname [3] Gender [4] Occupation
    [5] Country code [6] Area code [7] Phone number
    [8] None – Go back to main menu
    Enter choice: 1
    Enter new student number: 2005-67
    Then after the new information has been entered, the “edit menu” should again pop, now displaying the modified information. The said menu should keep on popping until the user selects

  8. #8
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by Matticus View Post
    Oh, and by the way, and cross-posting is considered very poor etiquette. C phonebook program return array - Stack Overflow

    oh boy. sorry about that. just this once. sorry sorry. that would be the last time. I prefer using this forum, really. I usually use the other forum for my php learnings. People there are sometimes cold, you know.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Let's clear up something before we proceed.

    Your first post mentions you're doing this to "help a friend". Now we see the clear specifications of an assignment. And the cross-posting (and "not enough time to redo the program" statement) implies that a deadline is imminent.

    Are you really doing this to help a friend?

    If so, then you are doing them no favors by completing their work for them. You should encourage them to sign up here and ask these questions for themselves.

    If not, then you have been less than honest about your situation, and a clarification is in order.

  10. #10
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by Matticus View Post
    Let's clear up something before we proceed.

    Your first post mentions you're doing this to "help a friend". Now we see the clear specifications of an assignment. And the cross-posting (and "not enough time to redo the program" statement) implies that a deadline is imminent.

    Are you really doing this to help a friend?

    If so, then you are doing them no favors by completing their work for them. You should encourage them to sign up here and ask these questions for themselves.

    If not, then you have been less than honest about your situation, and a clarification is in order.
    Yes, I'm helping a friend but of course with something as an exchange :P I'm currently working in an IT company, therefore I'm already a college graduate, no need to worry about spoonfeeding hehe. Really I'm done with C. I just use C in microcontrollers but I ain't no proficient in that either.

    I've been using forums since I started in programming. That was my secret when I was in college why my classmates look up to me, but I'm not really good compared to others. I'm really helping a friend, if this is for me, I wouldn't definitely tell all of these Some of the juniors in my college seek help from me for their projects, they do not use C/C++, so I can't refer them to this forum.

    Glenn

  11. #11
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    I'm not sure if my friend is currently a working student. He doesn't have much time for this project, but I'm sure he's passing his tests. no lying. I know that he is the one who's losing something by letting me do this program. Anyway, thank you for the help so far.

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Yes, I'm helping a friend but of course with something as an exchange
    Hmm - that sounds ethically questionable. Your friend is cheating, and you are gaining by helping them cheat. I don't want to come off like I'm on some moral high horse, but quite honestly, I do not wish to contribute to a situation like this. And apart from the ethical issues of the arrangement, it's probably not a good idea to take on work that you're not qualified for.

    I will answer one more thing for you, to wrap up the original advice I gave, but that's all I'm personally willing to help with.

    The code that I have is just for printing all the info, but I need to filter it using the name given by the user.
    You already have such "filter" code in your "find_name()" function. Just find a way to combine the two ideas (filtering by name, and printing).

  13. #13
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Hey sir Matt, or Matticus, thanks for all the help.
    I have deleted the DELETE case for a while. It's now working. damn this brain, doesn't work well in late nights. Didn't think of that idea @_@.

    In case some one will search for this phonebook program, I will just leave the code below, but it is not 100% complete, I just solved my searching problem lol.

    Code:
    /*
     * phonebook.c
     */
    
    
    #include <stdio.h>
    
    
    
    
    
    
    /*
     * A simple phonebook application.  Stores names/phone numbers in memory.
     * User can add, delete, or list names in the phone book.  The entries
     * are maintained in alphabetical by name.  The contents of the phone
     * book are not written to disk when the program is terminated.
     */
    /*
     * phonebook.h
     */
    
    
    /*
     * Constants/structure definitions for the phonebook application.
     */
    
    
    /* Capacity of the phonebook */
    
    
    #define CAPACITY 100
    
    
    /* User commands */
    
    
    #define ADD 'a'
    #define DELETE 'd'
    #define FIND   'f'
    #define LIST   'l'
    #define QUIT   'q'
    
    
    #define NAME_LEN 80
    #define NUMBER_LEN 40
    
    
    /* In memory representation of an entry in the phonebook. */
    
    
    typedef struct {
      char name[ NAME_LEN ];
      char number[ NUMBER_LEN ];
    } phone_record;
    
    
    /* Procedures in phonebook.c */
    
    
    char get_command( void );
    phone_record *get_record( void );
    void add_record( phone_record *new_record );
    void list_phonebook( void );
    void find_name( char *name );
    void delete_name( char *name );
    
    
    int num_entries;           // Number of entries currently in the phone book
    phone_record **phonebook;  // Where the names are stored
    
    
    int main( int argc, char **argv ) {
      char ch;
      char name[ NAME_LEN ];
      char confirm[ 10 ];
      phone_record *rec;
      int loc;
    
    
      // Create an empty phonebook
      phonebook = (phone_record **)malloc( sizeof( phone_record *) * CAPACITY );
      num_entries = 0;
    
    
      // Read commands until the user gets tired
      while ( ( ch = get_command() ) != QUIT ) {
        switch( ch ) {
          case ADD:
            // Get new info
            rec = get_record();
    
    
    	add_record(rec);
            break;
    
    
          case DELETE:
    
    
            break;
    
    
          case FIND:
            // Name to find
            printf( "Name:  " );
            scanf( "%s", name );
    
    
            // Look for the name
    		find_name(name);
            break;
    
    
          case LIST:
            // List the phonebook
            list_phonebook();
            break;
        }
      }
    }
    
    
    /* 
     * Read and return a command from the keyboard. 
     */
    char get_command() {
      char line[ 80 ];
    
    
      do {
        // Get input
        printf( "pb> " );
    
    
        // scanf returns -1 when it encoutners EOF - pretend we saw quit
        if ( scanf( "%s", line ) == -1 ) {
          line[ 0 ] = QUIT;
          printf( "\n" );  // Add new line so terminal looks nice
        }
      
        // Verify input (lightly)
        switch( line[ 0 ] ) {
          case ADD:
          case DELETE:
          case FIND:
          case LIST:
          case QUIT:
            break;
          default:
            printf( "Unrecognized command\n" );
            line[ 0 ] = 0;
        }
      } while ( line[ 0 ] == 0 );
    
    
      return line[ 0 ];
    }
    
    
    /*
     * Add a new record to the phonebook.
     */
    void add_record( phone_record *new_record ) {
      int cur;
    
    
      // Make sure there is room
      if ( num_entries == CAPACITY ) {
        printf( "Sorry phonebook is full\n" );
      }
      else {
        // Insertion sort.  Start at bottom and copy elements down one until
        // you find the first one less than what we are adding or we hit the
        // top of the phonebook
        for ( cur = num_entries; 
              cur > 0 && strcmp( phonebook[ cur - 1 ]->name, new_record->name ) > 0;
              cur = cur - 1 ) {
    
    
          phonebook[ cur ] = phonebook[ cur - 1 ];
        }
    
    
        // Add the entry in the open slot
        phonebook[ cur ] = new_record;
        num_entries = num_entries + 1;
      }
    }
    
    
    /*
     * List the entries in the phonebook.
     */
    void list_phonebook() {
      int i;
    
    
      if ( num_entries != 0 ) {
        printf( "Name\t\tNumber\n" );
        printf( "----\t\t------\n" );
    
    
        for ( i = 0; i < num_entries; i = i + 1 ) {
          printf( "%s\t\t%s\n", phonebook[ i ]->name, phonebook[ i ]->number );
        }
      }
      else {
        printf( "There are no entries in the phonebook\n" );
      }
    }
    
    
    /*
     * Delete the specified name from the phonebook.
     */
    void delete_name( char *name ) {
      int found;
      int i;
    
    
      // Start at the top looking for the record to delete.  Once it is
      // found starting moving elements in the phonebook up one
      // position.
      for ( i = 0, found = 0; i < num_entries; i = i + 1 ) {
        if ( !found ) {
          found = strcmp( name, phonebook[ i ]->name ) == 0;
        }
        else {
          phonebook[ i - 1 ] = phonebook[ i ];
        }
      }
    
    
      if ( found ) num_entries = num_entries - 1;
    }
    
    
    /*
     * Find a name in the phonebook.  -1 means it is not there.
     */
    void find_name( char *name ) {
    
    
    
    
      int i;
    
    
      if ( num_entries != 0 ) {
        printf( "Name\t\tNumber\n" );
        printf( "----\t\t------\n" );
    
    
        for ( i = 0; i < num_entries; i = i + 1 ) {
        	if ( strcmp( name, phonebook[ i ]->name ) == 0 )
          printf( "%s\t\t%s\n", phonebook[ i ]->name, phonebook[ i ]->number );
        }
      }
      else {
        printf( "There are no entries in the phonebook\n" );
      }
    }
    
    
    /*
     * Read and return a phone record from the keyboard.
     */
    phone_record *get_record() {
      phone_record *rec;
      char *name;
      char *number;
    
    
      // Allocate storage for the phone record.  Since we want the record
      // to live after the function returns we need to use malloc
      rec = (phone_record *)malloc( sizeof( phone_record ) );
    
    
      // Get the data
      printf( "Name:  " );
      scanf( "%s", rec->name );
    
    
      printf( "Phone:  " );
      scanf( "%s", rec->number );
    
    
      return rec;
    }
    Alright, this is the truth: he is my friend, I began looking for a 'part time jobs' when I was in 2nd year college. I accepted some programming projects to get paid. I was thinking I'm not the one who will get a disadvantage in doing this. I don't care if they graduate without knowing this C programming, as long as they have the basic knowledge, it's okay. because that's the truth, you won't be applying ALL the hard things in programming in your job someday. Some of it yes, like the logic, etc... If I studied so hard in C when I was in college and then my work right now is about C language, then it's good for me. But what I'm saying, again, is that not all the things you learn in school will be applied in your job. I'm the one who's getting the benefits. I think I'm not being selfish here. but hey again, thank you. I appreciate sir your effort. Some of the people in other forums are just quite 'mean' when answering my questions, especially when they know I'm from a different country

    I'll continue posting some questions here or reading some articles, if that's okay with you sir

    Glenn

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inheritance Phonebook Program
    By carpeltunnel in forum C++ Programming
    Replies: 16
    Last Post: 04-18-2013, 03:12 PM
  2. PHONEBOOK in c
    By chie22 in forum C Programming
    Replies: 6
    Last Post: 10-17-2011, 03:26 PM
  3. Need a hand with a Phonebook program
    By spade914 in forum C Programming
    Replies: 2
    Last Post: 10-05-2009, 10:28 PM
  4. phonebook help
    By noob2c in forum C Programming
    Replies: 5
    Last Post: 04-19-2003, 01:51 PM
  5. phonebook
    By jk81 in forum C Programming
    Replies: 6
    Last Post: 09-25-2002, 04:41 AM

Tags for this Thread