简体   繁体   中英

Writing a case-insensitive sort using qsort

I am trying to write a case-insensitive sort with qsort. However, I'm having trouble converting the const void * into a const char * to compare strings. Here is what I have so far:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int case_insensitive_string_sort (const void * a, const void  *b) {

    int a_len = strlen(a);
    char a_char, b_char;
    printf("%d", a_len);

    for (int i=0; i<=a_len; i++) {
        a_char = tolower((char*) a[i]);
        b_char = tolower((char*) b[i]);
        if (a_char != b_char)
            return b_char - a_char;
    }

    return 0;

}

int main(int argc, char *argv[]) {

    // example doing the comparison with known input to see if it works
    // int a = case_insensitive_string_sort("axxx", "ab");

    qsort(argv, argc, sizeof(argv[0]), case_insensitive_string_sort);
    for (int i=0; i<argc; i++)
        printf("<%s>, ", argv[i]);

  }

How would I properly do that?

You're certainly going to have trouble

converting the const void * into a const char * to compare strings.

because the array you are sorting ( argv ) is an array of char* , not an array of char . And the comparison function used by qsort is provided with pointers to the objects being sorted, not the objects themselves. [Note 1]

So if your comparison function was receiving a char * (cast to void * ), you would be comparing characters. Since you are in fact comparing character strings -- ie, arrays of characters -- you should expect a char** (cast to void* ).

One pretty ugly way of handling that would be:

> a_char = tolower(((char**) a)[i]);

But my preference is to cast the arguments once at the top of the function:

int my_compare(void* va, void* vb) {
  char** a = va;
  char** b = vb;
  /* ... */
}

I don't do that for efficiency; it probably produces the same code. I do it because I find it easier to read.

Notes

  1. C doesn't have any way to pass an object of unknown type by value. But you can pass a pointer to an object of unknown type by casting the pointer to a void* , as long as the function being called has a way to know what the original type of the pointer was.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM