Search code examples
c++cqsort

Qsort based on a column in a c-string?


A class project involves sorting an array of strings, with each string containing an equal number of columns like this:

Cartwright   Wendy    93
Williamson   Mark     81
Thompson     Mark     100
Anderson     John     76
Turner       Dennis   56

The program accepts a command-line argument for which column to sort on, and should print out the sorted strings unmodified.

I would like to use strtok to break up copies of each string into columns, and make structs for each line like this:

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}

My problem is in the comparison function pointer that qsort takes as an arg. If I understand correctly, the comparison function must take two const void pointers to the items to be sorted, and return an int. This means I can't pass pointers to structs into the comparison function because that is not what qsort will be sorting. I can't pass in the column number to sort on to the comparison function, because it can only take two args. How can I get around this to sort these strings based on specific columns?

edit: Sorting is limited to qsort or my own if I really want. Give the choice, I choose qsort. :)

edit # 2:The consensus seems to be either use a global variable for the column number, or just use qsort to sort an array of structs. I hadn't thought of just sorting the structs, and using the pointer in them to print out the original string. I think that is what I will do. Thanks for the help all!


Solution

  • 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);