2015-06-24 2 views
1

Я не могу понять, как использовать qsort. Я хочу отсортировать массив строк. Вроде так:Использование qsort в C по массиву строк

John    Adam 
Adam  ->  John 
Stacy    Stacy 

Однако ничего не работает. Я попытался скопировать то, что использовали другие (около 5 различных функций qsort из разных источников), и ничего не сработало. У меня есть один для int, который работает (назад, но по крайней мере он работает).

Вот необходимый код у меня есть:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

typedef struct { 
char name[80]; 
int age; 
} RECORD; 
RECORD record[25]; 

int main (int argc, char *argv[80]){  // Using command line to get my strings 

    int i = 2, j; 
    for(j = 0; j < (argc/2); j++)  //Converting and storing my ages 
    { 
     record[j].age = atoi(argv[i]); 
     i = i + 2; 
    } 

    int p, q = 1; 
    for(p = 0; p < (argc/2); p++) 
    { 
     strcpy(record[p].name, argv[q]); 
     q = q + 2; 
    } 
} 

int compareByName(const void* a, const void* b) //The qsort that doesn't work at all 
{ 
    const char *ia = (const char *)a; 
    const char *ib = (const char *)b; 

    return strncmp(ia, ib, 25); 
} 

int compareByAge (const void * a, const void * b) //My other qsort that works backwards 
{ 

    RECORD *RECORDA = (RECORD *)a; 
    RECORD *RECORDB = (RECORD *)b; 

    return (RECORDB->age - RECORDA->age); 
} 

void printRecords(RECORD r[], int num){ 
//printing stuff here 

double size = sizeof r[0]; 
double count = sizeof(r)/size;   //My qsort with size stuff, doesn't work 
qsort(r, count, size, compareByName); // if I do it the same as the other 

qsort (r, 25, sizeof(RECORD), compareByAge); //My other qsort that works backwards 

//more printing stuff here 
} 
+0

Не то, чтобы возрасты, вероятно, переполнялись, но чтобы избежать переполнения, используйте '(RECORDB-> age> RECORDA-> age) - (RECORDB-> возраст < RECORDA-> возраст) ' – chux

ответ

4

Вы не массив строк, то есть массив RECORD с, и это звучит, как вы хотите отсортировать этот массив на основе строк в массиве записей name. Итак, вы хотите что-то вроде:

int compareByName(const void *a_, const void *b_) { 
    RECORD *a = a_, *b = b_; 

    return strcmp(a->name, b->name); 
} 

, а затем вы вроде с

qsort (r, 25, sizeof(RECORD), compareByName); 
1

Хорошо, я вижу несколько проблем здесь.

Стоит отметить, что sizeof оценивается во время компиляции, поэтому вы не можете использовать sizeof(r), чтобы определить размер массива динамического размера, который вы передали. Я собираюсь догадаться, поэтому num передано в printRecords.

Как указывает @Chris, вы сортируете RECORD структуры, а не указатели на символы, поэтому функцию сравнения и вызовы обоих необходимо учитывать.

У вас есть вычитание, отклоненное в сравнении с возрастом - ему нужно вернуть отрицательное число, если левая сторона меньше правой стороны, поэтому используйте RECORDA->age - RECORDB->age.

1

Во-первых, это не то, что ваши строки не сортируются), double count = sizeof(r)/size; неправ. sizeof (r) не делает того, чего вы ожидаете. Вам нужно будет пройти размер массива printRecords(), как описано в этом вопросе:

How to get the length of array in C? is "sizeof" is one of the solution?

Во-вторых выключен, int compareByAge (const void * a, const void * b) //My other qsort that works backwards это назад, потому что вы делаете это в обратном направлении. Функции компаратора всегда возвращают A - B, а не B - A.

+0

Спасибо, я исправил проблему sizeof. Когда я заменяю «RECORDB-> age - RECORDA-> age» на «RECORDA-> age - RECORDB-> age», qsort перестает работать вообще и дает мне пустые данные для моей функции печати. То же самое с моим теперь работающим именем qsort. Если я попытаюсь правильно их перевернуть, они дадут пустые данные. – Rick

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