如何排序char **?

时间:2013-08-22 23:55:21

标签: c arrays string sorting

我有一个字符串数组。 不幸的是,字符串数组中每个字符串的大小不是常量,所以我不能这样做:

qsort(fileList, noOfFiles, sizeof(*fileList), compare); 

并制作自定义比较功能。 什么可以替代?

fileList是文件名列表。声明为:char **fileList;

我不能这样做的原因是因为qsort有点盲目的功能。  为了找到下一个元素,它只是跳过所述(第三个参数)内存单元。盲目。 如果使用可变长度字符串,则会导致随机行为。因为没有办法通过qsort识别字符串的开始和结束内存位置。

qsort可用于char * array [100]。

以下是许多人要求的错误代码:

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

int compare(const void *string1, const void *string2){

    char *a = (char*)(string1);
    char *b = (char*)(string2);
    printf("comparing %s     AND    %s\n", a, b);
    return strcasecmp(a,b);
}


void sortListName(char **fileList, int noOfFiles){
    printf("Sorting\n");
    qsort(fileList, noOfFiles, sizeof(char*), compare); 
    return;
}

3 个答案:

答案 0 :(得分:3)

如果您知道元素的数量,则可以对它们进行排序,无论每个字符串是否大小相同。

将compare定义为:

    int compare(const void *a,const void *b)
    {
      const char *astr = (char*)a;
      const char *bstr = (char*)b;    
      return strcmp(astr,bstr);
    }

答案 1 :(得分:3)

这取决于你的结构在内存中的布局:

如果您的char **sort_this如下所示:

  

| char * | char * | char * | ...

然后您可以使用qsort轻松对其进行排序。你有一个char *的数组来排序。此数组的长度是元素的数量,元素的宽度是sizeof(char *)。你的自定义比较函数也很简单:它是strcmp的包装器(你需要一个包装器,因为你将传递char *的地址而不是char *)。

所以

int compare (void *lhs, void *rhs)
{
        return strcmp(*(char **)lhs, *(char **)rhs)
}

但是,如果你在内存中有char *sort this这样的内容:

  

“此字符串为长\ 0”,“短\ 0”,“中等长度\ 0”,...

这样每个字符串都是连续的,那么你必须编写自己的排序例程。但是移动字符串会变成一场噩梦(交换相邻的字符串会很好,所以我会使用冒泡排序,它也很容易编码并且在已排序的列表上运行良好)。

但更好的想法是将数组重新排列为指向char *的指针并使用上述方法。

答案 2 :(得分:3)

这是正确的实施:

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

int compare(const void* v1, const void* v2){

    const char* a = *(char**)v1;
    const char* b = *(char**)v2;
    printf("comparing %s     AND    %s\n", a, b);
    return strcasecmp(a,b);
}


void sortListName(char** fileList, int noOfFiles){
    printf("Sorting\n");
    qsort(fileList, noOfFiles, sizeof(*fileList), compare); 
}

int main(void){
    char** fileList = malloc(3 * sizeof *filelist);

    fileList[0] = "Hello";
    fileList[1] = "World";
    fileList[2] = "forever";
    sortListName(fileList, 3);
    return 0;
}