使用qsort编写不区分大小写的排序

时间:2019-09-21 23:29:22

标签: c

我正在尝试使用qsort编写不区分大小写的排序。但是,我在将const void *转换为const char *以比较字符串时遇到麻烦。这是我到目前为止的内容:

#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]);

  }

我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

您肯定会遇到麻烦

  

const void *转换为const char *以比较字符串。

因为要排序的数组(argvchar*的数组,而不是char的数组。 qsort所使用的比较功能随 pointers 一起提供给要排序的对象,而不是对象本身。 [注1]

因此,如果您的比较功能正在接收char *(广播到void *),则您将在比较字符。由于您实际上是在比较字符串(即,字符数组),因此您应该期望使用char**(广播到void*)。

一种非常丑陋的处理方式是:

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

但是我的首选是将参数一次在函数顶部强制转换

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

我不这样做是为了提高效率;它可能产生相同的代码。我这样做是因为我发现它更易于阅读。

注释

  1. C没有任何方法可以按值传递未知类型的对象。但是您可以通过将指针强制转换为void*来将 pointer 传递给未知类型的对象,只要被调用的函数能够知道指针的原始类型是什么原是。
相关问题