#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    Problem with function..


    I am writing a program that will take the data from a structure, output it then re-arrange it by age lowest to highest and out put the list again.

    Here is what I have so far:
    Code:
    #include <stdio.h>
    
    struct person
    {
      char first_name[20];
      char last_name[20];
      int age;
    };
    
    void print_person_info(struct person clone);
    void sort_by_age(int n, struct person a[]);
    
    int main(void)
    {
    
      int i, n=5;
    
      struct person student[5] =
    {
      {"Bob", "Smith", 21},
      {"Jimmy", "John", 18},
      {"Amy", "Goldberg", 20},
      {"Dan", "Marlo", 17},
      {"Sally", "Sorrow", 16}
    };
    
      for(i=0; i<n; i++)
        print_person_info(student[i]);
    
      printf("--- AFTER SORTING ---------------\n");
    
      return 0;
    }
    void print_person_info(struct person clone)
    {
        printf("Name = %-6s %-9s\nAge = %-3d\n\n", &clone.first_name, &clone.last_name, &clone.age);
    }
    This is the output:
    Name = Bob Smith
    Age = -1078474456

    Name = Jimmy John
    Age = -1078474456

    Name = Amy Goldberg
    Age = -1078474456

    Name = Dan Marlo
    Age = -1078474456

    Name = Sally Sorrow
    Age = -1078474456


    What I don't understand is why the age int is outputting the same wrong number. Can someone point out what I did wrong?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,364
    Rep Power
    1870
    > printf("Name = %-6s %-9s\nAge = %-3d\n\n", &clone.first_name, &clone.last_name, &clone.age);
    Yes, you sprayed & through all your printf parameters.

    Code:
    $ gcc -Wall -Wextra baz.c
    baz.c: In function ‘print_person_info’:
    baz.c:36:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat]
    baz.c:36:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char (*)[20]’ [-Wformat]
    baz.c:36:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘int *’ [-Wformat]
    If you have GCC, then use the warning options to tell you when you abuse printf/scanf (and many other things).
    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
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    Thank you!


    Originally Posted by salem
    > printf("Name = %-6s %-9s\nAge = %-3d\n\n", &clone.first_name, &clone.last_name, &clone.age);
    Yes, you sprayed & through all your printf parameters.

    Code:
    $ gcc -Wall -Wextra baz.c
    baz.c: In function ‘print_person_info’:
    baz.c:36:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat]
    baz.c:36:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char (*)[20]’ [-Wformat]
    baz.c:36:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘int *’ [-Wformat]
    If you have GCC, then use the warning options to tell you when you abuse printf/scanf (and many other things).
    In our book the examples showed them with &. So to clarify, is it because they are declared before main that I don't need the &? Also, how do go about using the warning options?

    Thank you!
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    scanf vs printf

    scanf needs addresses to know where to store the values, so you need to give it pointer values. & gives you the address of a variable, which satisfies scanf's needs. For %s, a char array's name is already a pointer, so you don't need & for %s.

    printf needs values, so you don't use & with printf. The only exception is if you want to output the address of a variable.

    Originally Posted by Rednoc
    In our book the examples showed them with &.
    Get another book. Or else read your book again to verify what it says. You might also tell us the title and author in case someone else here has experience with it.


    Find the warnings option in your IDE. Turn warnings on and up. That last is because some IDEs allow you to set warning levels. You want to display all warnings. If you use gcc from the command line, then use the -Wall option.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    Lightbulb


    Get another book. Or else read your book again to verify what it says. You might also tell us the title and author in case someone else here has experience with it.


    Find the warnings option in your IDE. Turn warnings on and up. That last is because some IDEs allow you to set warning levels. You want to display all warnings. If you use gcc from the command line, then use the -Wall option.
    Ahhhh that's it... I see what I did wrong, initially I was declaring a pointer and needed the address, but then I decided this was faster and didn't remove them. Thank you!
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    One more question..


    Now I need to sort the structure to print out in ascending age order.

    This is what I came up with based on the format provided by the instructor, but I can't get it to work. Can someone point out the error?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct person
    {
      char first_name[20];
      char last_name[20];
      int age;
    };
    
    void print_person_info(struct person clone);
    void sort_by_age(int n, struct person a[]);
    
    int main(void)
    {
    
      int i, n=5;
    
      struct person student[5] =
    {
      {"Bob", "Smith", 21},
      {"Jimmy", "John", 18},
      {"Amy", "Goldberg", 20},
      {"Dan", "Marlo", 17},
      {"Sally", "Sorrow", 16}
    };
    
      for(i=0; i<n; i++)
        print_person_info(student[i]);
    
      sort_by_age(n, student);
    
      printf("--- AFTER SORTING ---------------\n");
    
      for(i=0; i<n; i++)
        print_person_info(student[i]);
    
      return 0;
    }
    void print_person_info(struct person clone)
    {
      printf("Name = %-6s %-9s\nAge = %-3d\n\n", clone.first_name, clone.last_name, clone.age);
    }
    void sort_by_age(int n, struct person a[])
    {
      int i, j, temp;
      for(i=0; i<n-1; i++)
      {
        for(j=i+1; j<n; j++)
        {
          if(a[i] > a[j])
          {
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
          }
        }
      }
    }
    I get this error:

    p7.c:51: error: invalid operands to binary > (have 'struct person' and 'struct person')
    p7.c:53: error: incompatible types when assigning to type 'int' from type 'struct person'
    p7.c:55: error: incompatible types when assigning to type 'struct person' from type 'int'
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    185
    Rep Power
    82
    In your sort_by_age function, the temp variable is declared as an int. It should be declared as a person structure. Also, you should be comparing the age field as follows:

    Code:
    if(a[i].age > a[j].age)
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    Clarify..


    Originally Posted by BobS0327
    In your sort_by_age function, the temp variable is declared as an int. It should be declared as a person structure. Also, you should be comparing the age field as follows:

    Code:
    if(a[i].age > a[j].age)
    Okay, so I would declare temp as a struct and set it equal to person a[]?
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    185
    Rep Power
    82
    Originally Posted by Rednoc
    Okay, so I would declare temp as a struct and set it equal to person a[]?
    All you need to do is change the declaration.. IOW,

    change this..
    Code:
    int temp;
    to this..
    Code:
     person temp;
    After the above change is made, you must fix the comparison

    change this..
    Code:
     if(a[i] > a[j])
    to this...
    Code:
    if(a[i].age > a[j].age)
    Then compile and test the code.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    6
    Rep Power
    0

    Thank you!!!!


    Originally Posted by BobS0327
    All you need to do is change the declaration.. IOW,

    change this..
    Code:
    int temp;
    to this..
    Code:
     person temp;
    After the above change is made, you must fix the comparison

    change this..
    Code:
     if(a[i] > a[j])
    to this...
    Code:
    if(a[i].age > a[j].age)
    Then compile and test the code.
    Oh jeez... I changed the code to struct person temp; and it worked great!!! ^_^ I can't believe I missed those two things!

IMN logo majestic logo threadwatch logo seochat tools logo