Qsort of dynamically allocated array of dynamically allocated strings by string length 动态分配的字符串数组按字符串长度排序
Qsort of dynamically allocated array of dynamically allocated strings by string length
#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;
}
所以我尝试这样做,但它 returns 是一个未排序的数组,我不知道应该更改什么,有人知道该怎么做吗?
[更新 :]
忘了说了,应该是按字符串长度排序的
来自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-"strings",因此比较函数获得传递给 C-"strings" 的指针,即 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*)
,即 char
.
所以改变这个:
strings[i]=(char*)malloc(sizeof(char*));
成为:
strings[i] = malloc(sizeof(char));
的甚至更好(因为 sizeof (char)
是 1
的定义):
strings[i] = malloc(1);
只剩下 1 char
的 "string",它只允许您存储空字符串 (""
)。
你可能想要 N
chars
?
也是
strings[i] = malloc(N + 1); /* 1+ for the 0-terminator. */
注意:在 C 中不需要强制转换 malloc()
(& Friends) 的结果,也不推荐。
最后确保用户在输入过程中不会溢出目标变量。
所以你想改变这个
scanf("%s", strings[i]);
成为
scanf("%20s", strings[i]);
#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;
}
所以我尝试这样做,但它 returns 是一个未排序的数组,我不知道应该更改什么,有人知道该怎么做吗?
[更新
忘了说了,应该是按字符串长度排序的
来自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-"strings",因此比较函数获得传递给 C-"strings" 的指针,即 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*)
,即 char
.
所以改变这个:
strings[i]=(char*)malloc(sizeof(char*));
成为:
strings[i] = malloc(sizeof(char));
的甚至更好(因为 sizeof (char)
是 1
的定义):
strings[i] = malloc(1);
只剩下 1 char
的 "string",它只允许您存储空字符串 (""
)。
你可能想要 N
chars
?
也是
strings[i] = malloc(N + 1); /* 1+ for the 0-terminator. */
注意:在 C 中不需要强制转换 malloc()
(& Friends) 的结果,也不推荐。
最后确保用户在输入过程中不会溢出目标变量。
所以你想改变这个
scanf("%s", strings[i]);
成为
scanf("%20s", strings[i]);