c - 按字符串长度对动态分配的字符串数组进行 Qsort

标签 c sorting pointers dynamic-arrays c-strings

#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/

相关文章:

count_calls() 函数和返回值

java - 如何用Java编写位排序程序?

ios - 对 SKShapeNode 元素的数组进行排序

java - 将数组的顺序复制到新数组

c - C中带有字符的指针,无法调用值

c++ - 使用双指针时发生访问冲突

c - gdb - 使用管道进行调试

c - 查找所有带有 miniupnp 的 UPnP 网关

字符指针和 printf 函数

c - 如何让多个 POSIX 线程等待另一个线程开始