Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sorting members of structure array

Given a structure array (in C) I am attempting to print out the results in groups of gender and in sub order by numerical order. For example:

struct employee{
char gender[13]
char name[13];
int id;
};

Say I define the structure array like so:

struct employee info[2]={{"male","Matt",1234},{"female","Jessica",2345},{"male","Josh",1235}};

How could I go about printing the results like

1234 Matt
1235 Josh


2345 Jessica
like image 920
bardockyo Avatar asked Nov 14 '12 03:11

bardockyo


2 Answers

Use your favourite sorting algorithm on the struct array. When comparing two elements of the array to decide which is "greater", compare their genders; if the genders are the same, compare their numbers. (You may want to define a separate function to do this comparison, to make things clearer.) Afterwards, print the sorted array in order using the desired formatting. Keep track of when the gender switches from male to female so you can put in an extra three newlines, as in your example.

Edit: to borrow shamelessly from kallikak, you can just pass your comparison function to qsort, but have it return 1 if one struct is "greater", -1 if it is "less" and (if necessary) 0 if it is the same (using the procedure I outlined above). Take a look at How to write a compare function for qsort from stdlib? for help on writing a custom compare function.

like image 29
1'' Avatar answered Nov 05 '22 22:11

1''


You'll need to implement a sorting function that compares the structs as you require

int compare(const void *s1, const void *s2)
{
  struct employee *e1 = (struct employee *)s1;
  struct employee *e2 = (struct employee *)s2;
  int gendercompare = strcmp(e1->gender, e2->gender);
  if (gendercompare == 0)  /* same gender so sort by id */
    return e1->id - e2->id;
  else
    return -gendercompare;  /* the minus puts "male" first as in the question */
}

And then use qsort from the standard library.

qsort(data, count, sizeof(struct employee), compare);

Inside the compare function you may want to check for id being equal, then you can sort by name (also using strcmp()) however you like.

Edit: Just compiled and fixed this up. Here's a little test program

    #include <stdio.h>
    #include <stdlib.h>

    struct employee{
      char gender[13];
      char name[13];
      int id;
    };

    int compare(const void *s1, const void *s2)
    {
      struct employee *e1 = (struct employee *)s1;
      struct employee *e2 = (struct employee *)s2;
      int gendercompare = strcmp(e1->gender, e2->gender);
      if (gendercompare == 0)  /* same gender so sort by id */
        return e1->id - e2->id;
      else
        return -gendercompare;
    }

    main()
    {
      int i;
      struct employee info[]={{"male","Matt",1234},{"female","Jessica",2345},{"male","Josh",1235}};

      for (i = 0; i < 3; ++i)
        printf("%d\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);

      qsort(info, 3, sizeof(struct employee), compare);

      for (i = 0; i < 3; ++i)
        printf("%d\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
    }

With output:

$ ./a.exe
1234    male    Matt
2345    female  Jessica
1235    male    Josh
1234    male    Matt
1235    male    Josh
2345    female  Jessica
like image 78
kallikak Avatar answered Nov 05 '22 21:11

kallikak