Sorting strings using qSort

14,597

Solution 1

Please note: It is unusual to store C strings in two dimensional char arrays. It's more normal to have char *ary[], such as argv. That type cannot be sorted directly using qsort and strcmp, because qsort will pass char ** not char * to the comparison function. This is good for efficiency, the pointers can be swapped instead of the whole strings. The Linux manpage for qsort has some good example code with a correct comparison function.

You can't pass strcmp directly to qsort as its comparison function because qsort expects to pass pointers to void where strcmp expects pointers to const char. Given the required similarity between pointers to void and pointers to char, you could probably do it with a cast (for your code), but the cleaner way would be to write a function that takes the right types:

int cmpstr(void const *a, void const *b) { 
    char const *aa = (char const *)a;
    char const *bb = (char const *)b;

    return strcmp(aa, bb);
}

Note, however, that in C++ you'd normally want to use std::sort instead of qsort, and probably use std::string instead of char *, which case the sorting gets a lot simpler (and generally faster as well).

Solution 2

The fourth argument of qsort takes 2 void* pointers as args.So you need to define a compare function for yours. refer to this link for more details.

Solution 3

You can pass strcmp directly to qsort

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char list[5][4]={"dat","mai","lik","mar","ana"};
int main(int argc, char *argv[]) {
    int x;
    puts("unsorted:");
    for (x=0;x<sizeof(list)/sizeof(list[0]);x++)
        printf("%s\n",list[x]);

    qsort(list,sizeof(list)/sizeof(list[0]),sizeof(list[0]),strcmp);

    puts("sorted:");
    for (x=0;x<sizeof(list)/sizeof(list[0]);x++)
        printf("%s\n",list[x]);
//  system("PAUSE");
    return EXIT_SUCCESS;
}

use C, not C++

Share:
14,597
user466444
Author by

user466444

Updated on June 19, 2022

Comments

  • user466444
    user466444 about 2 years

    According to this site, I have done the following program which sorts strings.

    #include <cstdlib>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    char list[5][4]={"dat","mai","lik","mar","ana"};
    int main(int argc, char *argv[])
    {
        int x;
        puts("sortirebamde:");
         for (x=0;x>sizeof(list)/sizeof(char);x++)
         printf("%s\n",list[x]);
          qsort(&list,(sizeof(list)/sizeof(char)),sizeof(list[0]),strcmp);
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    Here is the error I get

    13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp invalid conversion from `int (*)(const char*, const char*)' to `int (*)(const void*, const void*)' 
    13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp   initializing argument 4 of `void qsort(void*, size_t, size_t, int (*)(const void*, const void*))' 
    

    Please help

  • Sam Watkins
    Sam Watkins over 9 years
    This function will work for the question as posed, but that is not a good way to sort strings. This will not work to sort an array of char *, as qsort will pass char ** to the function.
  • Sam Watkins
    Sam Watkins over 9 years
    Do not pass strcmp directly to qsort, in the normal case (sorting an array of char *) it will not work, and it's always a type violation.
  • Jerry Coffin
    Jerry Coffin over 9 years
    @SamWatkins: Let me get this straight. You're downvoting because I answered the question he asked, instead of telling him how to do something almost (but not quite) completely different from what he asked?
  • Sam Watkins
    Sam Watkins over 9 years
    Ok, maybe that's unfair. I proposed an edit to your answer and will removed the downvote if the edit is accepted. (can't remove it right now due to "the rules" )
  • kuszi
    kuszi over 8 years
    for completeness, the cast version version would be: (int ()(const void, const void *))strcmp), see the working example