#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 20
int compare(const void* a, const void* b) {
return strlen((char*)a) - strlen((char*)b);
}
int main() {
int i, n;
scanf("%d", &n);
char** strings = malloc(n*sizeof(char*));
for(i=0; i<n;i++) {
strings[i]=(char*)malloc(sizeof(char*));
scanf("%s", strings[i]);
}
qsort(strings, n, sizeof(char*), compare);
for(i=0; i<n;i++)
printf("%s\n", strings[i]);
for(i=0; i<n;i++)
free(strings[i]);
free(strings);
return 0;
}
所以我尝试这样做,但它返回一个未排序的数组,我不知道应该更改什么,有人知道该怎么做吗?
<小时/>[更新from comment :]
我忘记说了,它应该按字符串长度排序。
最佳答案
来自C11 Standard (draft) on the qsort()
function (我强调的):
The contents of the array are sorted into ascending order according to a comparison function pointed to by compar, which is called with two arguments that point to the objects being compared.
显示的代码想要比较 C-“字符串”,因此比较函数会传递指向 C-“字符串”的指针,即 char**
(此处)。
您的代码将参数视为 char *
。
要修复此更改:
int compare(const void* a, const void* b) {
return strlen((char*)a) - strlen((char*)b);
}
成为:
int compare(const void * pv1, const void * pv2) {
char * ps1 = *(char **) pv1;
char * ps2 = *(char **) pv2;
return strlen(ps1) - strlen(ps2);
}
或者(为了避免强制转换)执行以下操作:
int compare(const void * pv1, const void * pv2) {
char ** ppc1 = pv1;
char ** ppc2 = pv2;
return strlen(*ppc1) - strlen(*ppc2);
}
注意:上面的两个片段都默认假设 strings
中没有元素为 NULL
。
此外,当分配给 char*
时,会分配 char*
指向的大小块,即 *(char*)
,即 字符
。
所以改变这个:
strings[i]=(char*)malloc(sizeof(char*));
成为:
strings[i] = malloc(sizeof(char));
甚至更好(因为 sizeof (char)
是 1
的定义):
strings[i] = malloc(1);
这只会留下 1 个 char
的“字符串”,它允许您仅存储空字符串 (""
)。
您可能需要N
字符
?
也这样
strings[i] = malloc(N + 1); /* 1+ for the 0-terminator. */
注意:在 C 中,不需要强制转换 malloc()
(& Friends)的结果,也不建议这样做。
最后确保用户在输入过程中不会溢出目标变量。
所以你想改变这个
scanf("%s", strings[i]);
成为
scanf("%20s", strings[i]);
关于c - 按字符串长度对动态分配的字符串数组进行 Qsort,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37772993/