#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMELEM(a) (sizeof(a)/sizeof(a[0]))

struct tag {
	int count;
	char *desc;
};

main()
{
	int cmpstia(const void *, const void *);
	int cmpstid(const void *, const void *);
	int cmpstsa(const void *, const void *);
	int cmpstsd(const void *, const void *);

	static struct tag array[] = {
		{123, "beds"},
		{27,  "tables"},
		{17,  "chairs"},
		{95,  "desks"}
	};
	int (*cmpfun[])(const void *, const void *) = {
		cmpstia, cmpstid, cmpstsa, cmpstsd
	};
	int option = 0;
	int i;

	puts("1. Sort by ascending count");
	puts("2. Sort by descending count");
	puts("3. Sort by ascending description");
	puts("4. Sort by descending description\n");

	while (1) {
		printf("Enter option: ");
		scanf("%1d", &option);
		if (option < 1 || option > 4)
			puts("Invalid option");
		else
			break;
	}

	qsort(&array[0], NUMELEM(array), sizeof(struct tag),
		cmpfun[option - 1]);

	for (i = 0; i < NUMELEM(array); ++i)
		printf("array[%d]: count = %3d, desc = >%s<\n",
			i, array[i].count, array[i].desc);

	return 0;
}

/* compare ints in ascending order */

int cmpstia(const void *pe1, const void *pe2)
{
	return ((struct tag *)pe1)->count -
		((struct tag *)pe2)->count;
}

/* cmpstid ints in descending order */

int cmpstid(const void *pe1, const void *pe2)
{
	return ((struct tag *)pe2)->count -
		((struct tag *)pe1)->count;
}

/* compare strings in ascending order */

int cmpstsa(const void *pe1, const void *pe2)
{
	return strcmp(((struct tag *)pe1)->desc, 
		((struct tag *)pe2)->desc);
}

/* compare strings in descending order */

int cmpstsd(const void *pe1, const void *pe2)
{
	return -strcmp(((struct tag *)pe1)->desc, 
		((struct tag *)pe2)->desc);
}

1. Sort by ascending count
2. Sort by descending count
3. Sort by ascending description
4. Sort by descending description

Enter option:1
array[0]: count =  17, desc = >chairs<
array[1]: count =  27, desc = >tables<
array[2]: count =  95, desc = >desks<
array[3]: count = 123, desc = >beds<

Enter option:2
array[0]: count = 123, desc = >beds<
array[1]: count =  95, desc = >desks<
array[2]: count =  27, desc = >tables<
array[3]: count =  17, desc = >chairs<

Enter option:3
array[0]: count = 123, desc = >beds<
array[1]: count =  17, desc = >chairs<
array[2]: count =  95, desc = >desks<
array[3]: count =  27, desc = >tables<

Enter option:4
array[0]: count =  27, desc = >tables<
array[1]: count =  95, desc = >desks<
array[2]: count =  17, desc = >chairs<
array[3]: count = 123, desc = >beds<

