我有一个字符串数组。 不幸的是,字符串数组中每个字符串的大小不是常量,所以我不能这样做:
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;
}
答案 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;
}