Assuming you're not limited to using qsort, you can use std::sort, with a functor object that stores the column number. If you have to use qsort, one quick and dirty solution would be to store the column number in a global variable and use that in the comparisson function.
Different comparator functions, all of which take the whole struct, but each uses only one column for comparation.
C++ or C? Based on your tags, I assume it's C++. Let's try STL way.
You should use std::sort
instead of qsort
. std::sort
can take not only function pointer (compared to its C alternative), but any object that can be called as a function. You may know that class instances can be called as functions with operator()
. Then the solution is straightforward: create a "functor" class that will create different functions upon construction. The sort call would then look like that:
std::sort(array, array+size, comparator(2 /* sort by column #2 */));
The functor class effectively creates a so-called "closure": a dynamically created functional object that has local variables, but doesn't share them with other functional objects created this way. It would look like this:
class comparator{
private: unsigned int field_n;
public: comparator(unsigned int _field_n) : field_n(_field_n) {};
public: int operator () (char const * lhs, char const * rhs)
{ /* compare here fields with index field_n */ };
};
Note that instead of void pointers comparison "function" (i.e. the class instance you create) has char *
parameters, so you don't bother yourself with type casting.
In C, unfortunately, you can't do this the other way than creating a global variable.
You can pass the structs like this:
struct line {
char * line;
char column_to_sort_on[MAX_COLUMN];
}
...
line* Lines[max_lines]; // here you store the structs
int
cmp_lines( const void *elem1, const void *elem2 )
{
line* line1 = *(line**)elem1;
line* line2 = *(line**)elem2;
// do the comparisons
}
qsort(Lines, max_lines, sizeof(line*), cmp_lines);