-2

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

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;
}
4

3 回答 3

3

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

将比较定义为:

    int compare(const void *a,const void *b)
    {
      const char *astr = (char*)a;
      const char *bstr = (char*)b;    
      return strcmp(astr,bstr);
    }
于 2013-08-23T00:01:13.853 回答
3

这取决于您的结构在内存中的布局方式:

如果你有char **sort_this它看起来像这样:

| 字符 * | 字符 * | 字符 *|...

然后,您可以使用 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 * 的指针并使用上述方法。

于 2013-08-23T00:03:40.187 回答
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;
}
于 2013-08-23T01:13:14.297 回答