Using qsort to sort structure pointers by various variables

I am trying to understand the qsort c library in the context of pointers to structures. Here is the existing code that I would like to manipulate:

Structure:

#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
    char name[MAX_NAME+1];
    int monthSales[NUM_MONTHS];
    int total;
} Emp;

      

Global data initialization and size:

Emp *data;//where all entries are kept
int empSize;

      

and I have built 2 arrays of Emp pointers that I would like to use for data in different orders:

Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

      

after they have been identically assigned, I would like to use qsort to order them differently. nameArray alphabetically using the name in the structure and salesArray, smallest and smallest using the total in the structure

What should the comparison methods and qsort arguments look like?

thank

+3


source to share


2 answers


You just need to define two different comparison functions. Each comparison function must take two pointers to void (in which case you must use them for types Emp **

) and then return a negative integer, zero, or a positive integer if the first entry is less than, equal to, or greater than the second, respectively.

For a general sort, you can simply subtract the second total

from the first. If the first total is less than the second, this results in a negative number, and vice versa, when the first total is greater than the second. When they are equal, zero is returned.

int compareByTotal(const void *first, const void *second)
{
    int firstTotal = (*(Emp **)first)->total;
    int secondTotal = (*(Emp **)second)->total;

    return firstTotal - secondTotal;
}

      

The second, since this is a string comparison, can return a value strcmp

(which obeys the same return conventions):



int compareByName(const void *first, const void *second)
{
    const char *firstName = (*(Emp **)first)->name;
    const char *secondName = (*(Emp **)second)->name;

    return strcmp(firstName, secondName);
}

      

Then you can simply call qsort

, passing in the names of these functions:

/* given: */
Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

/* use: */
qsort(nameArray, empSize, sizeof(*nameArray), &compareByName);
qsort(salesArray, empSize, sizeof(*salesArray), &compareByTotal);

      

+3


source


An example of sorting by name:



#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
  char name[MAX_NAME + 1];
  int monthSales[NUM_MONTHS];
  int total;
} Emp;

int compareName(const void * a, const void * b)
{
  return (strcmp(((Emp*)a)->name, ((Emp*)b)->name));
}

int main()
{
  Emp *data;
  int empSize = 100;
  qsort(data, empSize, sizeof(Emp), compareName);
  // qsort(data, empSize, sizeof(Emp), compareSales);
  return 0;
}

      

+1


source







All Articles