使用stdlib的qsort()对字符串数组进行排序

一些序言:我是一名计算机工程专业的学生,​​经过3个学期的Java(直到数据结构),在C学习第一堂课。 这个问题与家庭作业有关,但是为我解决了几个步骤。

我有一个输入文件,我读入内存,它存储在char [9] [500]。 我读入最多500个最大长度为8的字符串。我试图使用stdlib内置的qsort()函数对这个数组进行排序,并且有一些内存错误。

重要的代码片段:

char data[4][500][60]; char debug[500][9]; size_t count = 0; /* initialize file, open for reading */ FILE* pUserlog; pUserlog = fopen("userlog","r"); while(!feof(pUserlog)) { fscanf(pUserlog, "%9s %8s %16s",debug[count], data[1][count], data[2][count]); fgets(data[3][count], 60, pUserlog); count++; } 

本节将数据读入数组。 这部分感兴趣的数组是“debug”。 这是上面指定的数组。 这是我的qsort比较函数:

 int compare(const void* a, const void* b) { const char **ia = (const char **)a; const char **ib = (const char **)b; puts("I'm in compare!"); return strncmp(*ia, *ib,8); } 

这是我尝试调用qsort:

 size_t debug_len = sizeof(debug)/sizeof(char*); printf("debug len: %d, count: %d, sizeof(char*): %d\n",debug_len,count,sizeof(char*)); qsort(debug,count, sizeof(char *), compare); 

我尝试在我的调用中替换debug_len,其中count是,但我仍然是segfaulting。 这是输出:

 $ ./test
 debug len:1125,count:453,sizeof(char *):4
我在比较!
分段故障(核心转储)

谢谢!

compare函数将接收指向要比较的元素的指针。 您正在尝试使用strncmp()比较字符。 由于您有指向每个字符串的指针,因此将其char *转换为char *并进行比较。

 int compare(const void* a, const void* b) { const char *ia = (const char *)a; const char *ib = (const char *)b; puts("I'm in compare!"); return strncmp(ia, ib, 9); } 

还要记住,它是一个数组数组,而不是一个指针数组。 所以元素的大小应该是数组的大小,而不是指针的大小, 4 。 此时,使用sizeof debug[0]会更容易,因为它是一个二维数组。 如果你没有使用正确的大小, qsort()只会破坏你的数组。

 size_t elemsize = sizeof debug[0]; /* 9 - size of each element */ size_t count = sizeof(debug)/elemsize; /* 500 - number of elements in array */ qsort(debug, count, elemsize, compare); 

这里发生的是:你有500个字符串。 现在你将所有500传递给qsort,然后它将每个传递给你的比较函数作为第一个和第二个参数。 这有点像写这个:

 compare(debug[0], debug[1]) 

C编译器传递地址,而不是当然的实际值。 但现在您将指向void的指针解释为指向指针的指针。 您的代码现在在调用strncmp时会取消引用,但这会使 (前4个字节)被视为strncmp的指针。 但strncmp现在反过来会尝试取消引用垃圾“指针”(它由你的一个字符串的一部分组成),这就是爆炸

要解决此问题,请使用char *而不是char **

 int compare(const void* a, const void* b) { puts("I'm in compare!"); return strncmp((const char *)a, (const char *)b, 8); }