Thread: need some help

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221

    need some help

    im trying to ask the user to enter there family names and ages into a database
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100
    
    /* proto functions *******************/
    void print( void );          
    void load_family ( void );
    void load_ages ( void );
    /**********************************/
    
    struct family {             // family database
           char name[BUFSIZ];
           char gender[BUFSIZ];
           int age;
           } tree[BUFSIZ];
    
    char name[BUFSIZ];  // global name
    
    int main(int argc, char *argv[]) {
        
    int i;
    printf( "what is your name : " );  
    fgets ( name , sizeof ( name ), stdin );    
    
    print();  // print function to display
    load_family();  // load function to load all the family names into database
           
        
      getchar();	
      return 0;
    }
    
    /************** print function *************************/
    void print ( void ) {
    printf("*********************************************\n" );
    printf( "%55s" ," ** welcome to the family catolog **\n" );
    
    }
    /****************** attempt to fill database **************************/
    
    void load_family ( void ) {
         int i;
         char ch;
         printf( "%s enter the all the names of your family.\n" , name );
         printf( "hit enter after each name ( q to stop ) : \n");
         for ( i = 0; i < MAX; ++i) {
         fgets ( tree[i].name , sizeof ( name ), stdin );
         ch = getche();
         if ( ch == 'q' )
         load_ages();
         
      }
    }
    /************** load ages function into database*************************//////
    void load_ages ( void ) {
         int i ;
         char ch;
         printf( "\n%s Now we will enter the ages of the family you entered!.\n" , name );
         printf( "hit enter after each age ( q to stop ) :\n ");
         for ( i = 0; i < MAX; ++i) {
         printf ( "family member :  %s ", tree[i].name );
         puts("enter the age now!");
         scanf ("%s" , &tree[i].age );
         ch = getche();
         if ( ch == 'q' )
         break;
      }
    }
    output:
    Code:
    what is your name : luke
    *********************************************
                       ** welcome to the family catolog **
    luke
     enter the all the names of your family.
    hit enter after each name ( q to stop ) :
    anakin
    padme
    leia
    q
    luke
     Now we will enter the ages of the family you entered!.
    hit enter after each age ( q to stop ) :
     family member :  anakin
     enter the age now!
    23
    family member :  adme
     enter the age now!
    17
    family member :  eia
     enter the age now!
    26
    family member :   enter the age now!
    as you can see i have to hit enter twice and it leaves off the first character in the name.
    what am i doing wrong?

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Use fgets (with sscanf or others for conversions) for all user input -- don't intermix with scanf or the nonstandard getche. Also, tell fgets the truth about string sizes.
    Code:
    fgets ( tree[i].name , sizeof ( name ), stdin );
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    thanks dave!
    im not really familiar with sscanf
    Code:
    sscanf ( tree[i].age , "%i" , &tree[i].age );
    i get an error
    63 C:\Dev-Cpp\files.c [Warning] passing arg 1 of `sscanf' makes pointer from integer without a cast

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Let's examine the code for a bit.
    Code:
    sscanf ( tree[i].age , "%i" , &tree[i].age );
    Now, instead of reading from the stdin stream, sscanf reads its input from a string. So, now does the error make sense?

  5. #5
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    ok i understand.
    Code:
    sscanf ( tree, "%s" , &tree[i].age );
    so tree would be the struct string
    and the tree[i].age is the int?
    why doesnt it work?
    sorry if this seems easy to you =(
    63 C:\Dev-Cpp\files.c [Warning] passing arg 1 of `sscanf' from incompatible pointer type

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You fgets() into a buffer
    You then sscanf(), or use whatever else you like, to extract what you want from that buffer and store it inside your data structure.

    > fgets ( tree[i].name , sizeof ( name ), stdin );
    Even this would go via a temporary buffer, followed by a string copy to tree[i ].name
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by mrsirpoopsalot
    im not really familiar with sscanf
    User Input: Strings and Numbers [C]
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    thank you guys for your help.
    i worked through it. it works but not sure if its right.
    Code:
    void load_ages ( void ) {
         int i ;
         char ch;
         char temp[BUFSIZ]; 
         printf( "\n%s Now we will enter the ages of the family you entered!.\n" , name );
         printf( "hit enter after each age ( q to stop ) :\n ");
         for ( i = 0; i < MAX; ++i) {
         printf ( "family member :  %s ", tree[i].name );
         puts("enter the age now!");
         fgets ( temp , sizeof ( temp )  , stdin );
          sscanf(temp , "%s" , &temp);
          tree[i].age = atol( temp ); 
         ch = getchar();
         if ( ch == 'q' )
         break;
      }
    }
    i may have more issues before this is all said and done

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    More like this.
    Code:
          fgets ( temp , sizeof ( temp )  , stdin );
          sscanf(temp , "%d" , &tree[i].age);
    The sscanf line to me reads, "scan the string temp, look for one integer, attempt to put the result into &tree[i].age.

    And yes, you still do have a number of issues.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100
    
    /* proto functions *******************/
    void print( void );          
    void load_family ( void );
    void load_ages ( void );
    /**********************************/
    
    struct family {             // family database
           char name[BUFSIZ];
           char gender[BUFSIZ];
           int age;
           } tree[BUFSIZ];
    
    char name[BUFSIZ];  // global name
    
    int main(int argc, char *argv[]) {
      
    int i;
    printf( "what is your name : " );  
    fgets ( name , sizeof ( name ), stdin );    
    
    print();  // print function to display
    load_family();  // load function to load all the family names into database
           
        
      getchar();	
      return 0;
    }
    
    /************** print function *************************/
    void print ( void ) {
    printf("*********************************************\n" );
    printf( "%55s" ," ** welcome to the family catolog **\n" );
    
    }
    /****************** attempt to fill database **************************/
    
    void load_family ( void ) {
         int i;
         char ch;
         printf( "%s enter the all the names of your family.\n" , name );
         printf( "hit enter after each name ( q to stop ) : \n");
         for ( i = 0; i < MAX; ++i) {
         fgets ( tree[i].name , sizeof ( tree[i].name ), stdin );
         ch = getchar();
         if ( ch == 'q' )
         load_ages();
         
      }
    }
    /************** load ages function into database*************************//////
    void load_ages ( void ) {
         int i ;
         char ch;
         char temp[BUFSIZ]; 
         printf( "\n%s Now we will enter the ages of the family you entered!.\n" , name );
         printf( "hit enter after each age ( q to stop ) :\n ");
         for ( i = 0; i < MAX; ++i) {
         printf ( "family member :  %s ", tree[i].name );
         puts("enter the age now!");
         fgets ( temp , sizeof ( temp ) , stdin );
         sscanf(temp , "%d" , &tree[i].age);
         //tree[i].age = atol( temp );
         ch = getchar();
         if ( ch == 'q' )
         break;
      }
    }
    what other issues do i have at this point?

  11. #11
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    sorry if this is sloppy or very ugly! im still new and learning. this isnt working right.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 100
    
    /* proto functions *******************/
    void print( void );          
    void load_family ( void );
    void load_ages ( void );
    void display_menu ( void );
    void search_name ( void );
    void display_catalog ( int i );
    void display_catalog2();
    /**********************************/
    
    struct family {             // family database
           char name[BUFSIZ];
           unsigned age;
           } tree[BUFSIZ];
    
    char name[BUFSIZ];  // global name
    
    int main(int argc, char *argv[]) {
      
    int i;
    printf( "what is your name : " );  
    fgets ( name , sizeof ( name ), stdin );    
    
    print();  // print function to display
    load_family();  // load function to load all the family names into database
           
        
      getchar();	
      return 0;
    }
    
    /************** print function *************************/
    void print ( void ) {
    printf("*********************************************\n" );
    printf( "%55s" ," ** welcome to the family catolog **\n" );
    
    }
    /****************** attempt to fill database **************************/
    
    void load_family ( void ) {
         int i;
         char ch;
         printf( "%s enter the all the names of your family.\n" , name );
         printf( "hit enter after each name ( q to continue ) : \n");
         for ( i = 0; i < MAX; ++i) {
         fgets ( tree[i].name , sizeof ( tree[i].name ), stdin );
         ch = getchar();
         if ( ch == 'q' )
         load_ages();
         
      }
    }
    /************** load ages function into database*************************//////
    void load_ages ( void ) {
         int i ;
         char ch;
         char temp[BUFSIZ]; 
         printf( "\n%s Now we will enter the ages of the family you entered!.\n" , name );
         printf( "hit enter after each age ( q to continue ) :\n ");
         for ( i = 0; i < MAX; ++i) {
         printf ( "family member :  %s ", tree[i].name );
         puts("enter the age now!");
         fgets ( temp , sizeof ( temp ) , stdin );
         sscanf( temp , "%d" , &tree[i].age);
         ch = getchar();
         if ( ch == 'q' )
         display_menu();
      }
    }
    void display_menu( void ) {
         int ch;
         printf( "\ncatalog search database:\n" );
         printf( " 1. search by name\n" );
         printf( " 2. display family tree\n" );
         printf( " 3. quit the program\n" );
         ch = getchar();
         switch ( ch ) {
                case 1: 
                search_name();
                break;
                case 2:
                display_catalog2();
                break;
                case 3:
                exit(0);
         default:
                 printf("wrong selection!");
                 getchar();
                 }
    }
                
       /*********** search name function ********/              
    void search_name ( void ) {
         int found = 0 , i;          
         printf( "name: ");
         for ( i = 0; i < MAX; ++i )
         fgets ( name , sizeof name , stdin );
         sscanf( name , "%d" , tree[i].name );
         if ( !strcmp ( name , tree[i].name )) {
         found = 1;
         display_catalog(i);
         }
         if( !found )
         puts("not found!");
    }
      
      /*VVVVVVVVVVVVVVVVVVV display catalog */
         
    void display_catalog ( int i )  {
         printf("%s\n" , tree[i].name );
         printf("age : %i\n" , tree[i].age );
    }
                     
    void display_catalog2() {
         int i;
         printf(" the names and there ages in your family tree are :\n" );
         for(i = 0; i < MAX; ++i ) {
         printf("%s , %i \n" , tree[i].name, tree[i].age);
         }
    }


    output:
    Code:
    what is your name : luke
    *********************************************
                       ** welcome to the family catolog **
    luke
     enter the all the names of your family.
    hit enter after each name ( q to continue ) :
    padme
    anakin
    leia
    q
    
    luke
     Now we will enter the ages of the family you entered!.
    hit enter after each age ( q to continue ) :
     family member :  padme
     enter the age now!
    18
    family member :  nakin
     enter the age now!
    38
    family member :  eia
     enter the age now!
    26
    family member :   enter the age now!
    q
    
    catalog search database:
     1. search by name
     2. display family tree
     3. quit the program
    wrong selection!
    it leaves off the first letter of there names plus catalog search database wont work!
    any help is much appreciated
    Last edited by mrsirpoopsalot; 10-07-2006 at 08:51 PM.

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Code:
         fgets ( tree[i].name , sizeof ( tree[i].name ), stdin );
         ch = getchar();
    getchar() is grabbing the first letter of people's names after fgets() returns, if you enter more than one name at a time. Obviously this isn't working very well, so I would just get rid of getchar(). You can use the buffer you know:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
       int c;
       char buff[17];
    
       while ( fgets(buff, sizeof buff, stdin) != NULL )
          if ( strchr(buff, '\n') == NULL ) {
             printf("scrubbing extra input\n");
             while((c = getchar()) != '\n' && c != EOF);
          }
          else if ( buff[0] == '\n' ) {
             printf("blank line entered - bye\n");
             break;
          }
          else {
             printf("a good line entered - %s\n", buff);
          }
    
       return 0;
    }
    /* thanks Salem for posting this */
    Just so you can see how it works:

    $ ./a
    hello world
    a good line entered - hello world

    afjfiofujafjkf afi;ojf kfak
    scrubbing extra input

    blank line entered - bye

  13. #13
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    i looked it over and i really dont understand
    Code:
    if ( strchr(buff, '\n') == NULL ) {
    printf("scrubbing extra input\n");
    so your looking for a newline in buff? where does the newline come from? does it work when you go over buff[17]? and it points to the first character before?
    sorry if this seems like a dumb question!
    Last edited by mrsirpoopsalot; 10-08-2006 at 07:16 AM.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > so your looking for a newline in buff?
    Type in 20 chars, press return and see what happens.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    so it looks like when it does go over the buffer it tacks on a newline?

Popular pages Recent additions subscribe to a feed