sorting members of structure array

bardockyo picture bardockyo · Nov 14, 2012 · Viewed 41k times · Source

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

Answer

kallikak picture kallikak · Nov 14, 2012

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.

Ken

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