按字符串长度

时间:2016-06-12 10:07:48

标签: 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:]

我忘了提,它应该按字符串的长度排序。

1 个答案:

答案 0 :(得分:0)

来自C11 Standard (draft) on the qsort() function(由我强调):

  

根据compar指向的比较函数,数组的内容按升序排序,使用两个参数调用指向到被比较的对象

显示的代码想要比较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*),即char

所以改变这个:

   strings[i]=(char*)malloc(sizeof(char*));

是:

   strings[i] = malloc(sizeof(char));

更好(因为sizeof (char) 1是定义):

   strings[i] = malloc(1);

只留下1 char的“字符串”,只允许您存储空字符串("")。

您可能需要N chars

所以

   strings[i] = malloc(N + 1); /* 1+ for the 0-terminator. */

注意:在C中,无需投射malloc()(&amp; Friends)的结果,也不建议使用。

最后确保用户在输入期间不会溢出目标变量。

所以你想改变这个

  scanf("%s", strings[i]);

  scanf("%20s", strings[i]);