2016-06-12 8 views
0
#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:]Qsort динамически распределенного массива динамически распределенных строк по длине строки

Я забыл упомянуть, что должен быть отсортирован по длине строки.

+2

'строки [я] = (символ *) таНос (SizeOf (Char *)),' должен быть 'строки [ i] = malloc (MaxLength); 'или так. Каковы ваши критерии сортировки? – mch

+0

О, да, я забыл упомянуть, он должен быть отсортирован по длине строк. – Nikola

+1

Помимо проблемы с malloc, упомянутой mch, ваша функция сравнения недействительна. – melpomene

ответ

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, которая позволяет хранить пустая строка ("") только.

Возможно, вы захотите chars?

Так что

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

Примечание: В C нет необходимости подавать результат malloc() (& друзей) и не рекомендуется.


Наконец, убедитесь, что пользователь не переполняет переменную назначения во время ввода.

Так что вы хотите изменить

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

быть

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

Это очень помогло. большое спасибо! – Nikola

 Смежные вопросы

  • Нет связанных вопросов^_^