Невозможно заставить qsort правильно работать со структурой - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь выяснить, как заставить qsort правильно работать с моим типом данных struct. По сути, я извлекаю содержимое хеш-таблицы в массив basi c, а затем пытаюсь отсортировать массив. Я понимаю, что, возможно, есть НАМНОГО лучший способ сделать все это, но я пока не очень хорошо разбираюсь с C, и моя главная цель - просто заставить это работать.

struct DataItem {
    int value;
    char* key;
};

typedef struct DataItem pair;

Вот сравните функцию и функцию, которая должна возвращать хэш-карту в виде отсортированного массива:

int cmp_pairs(const void* p1, const void* p2) {
    int l = ((pair*) p1)->value;
    int r = ((pair*) p2)->value;
    printf("Comparing: (%s, %d) and (%s, %d)\n", ((pair*)p1)->key,l,((pair*)p1)->key,r);
    return r - l;
}

pair** getSortedArr(hashtable *h) {

    pair **result = malloc(sizeof(pair*) * (h->itemCount)); /* Hold the number of pointers that it needs */
    int j = 0, i = 0;
    for (i = 0; i < h->size; ++i) { /* Iterate through hash array */
        if (h->hashArray[i] != NULL) {
            result[j++] = h->hashArray[i];
        }
    }
    printf("UNSORTED ARRAY\n");
    for (int i = 0; i < 5; ++i) {
        printf("%d: (%s, %d)\n", i, result[i]->key, result[i]->value);
    }

    qsort(result, j, sizeof(pair*), cmp_pairs);

    return result;
}

И вот главное:

hashtable table;
hashtable *t = &table;

int main(void) {
    init(t, 50);

    char* arr[6];

    arr[0] = "Hello";
    arr[1] = "Goodbye";
    arr[2] = "Sup";
    arr[3] = "How r u";
    arr[4] = "Good";

    int intarr[6];
    intarr[0] = 1;
    intarr[1] = 4;
    intarr[2] = 2;
    intarr[3] = 8;
    intarr[4] = 9;


    // int a = 1, b = 4, c = 2, d = 8, e = 8;

    printf("Elements in array: %lu\n", sizeof(arr)/sizeof(char*) - 1);

    for (int i = 0; i < 5; ++i) {
        //printf("Hashcode for %s: %lu\n", arr[i], hashCode(arr[i])%50);
        insert(t, arr[i], intarr[i]);
    }

    display(t);

    pair **array = getSortedArr(t);

    printf("\nSORTED ARRAY\n");
    for (int i = 0; i < 5; ++i) {
        printf("%d: (%s, %d)\n", i, array[i]->key, array[i]->value);
    }

    return 0;

}

Хеш-таблица работает отлично. Это делает свою работу, и даже извлечение в массив работает. Но qsort действует. Я думаю, что это связано с моей функцией сравнения, но похоже, что я правильно ее реализую. Вот вывод из операторов printf:

UNSORTED ARRAY
0: (Goodbye, 4)
1: (Sup, 2)
2: (Hello, 1)
3: (Good, 9)
4: (How r u, 8)
Comparing: (, 41968208) and (, 41968240)
Comparing: (, 41968208) and (, 41968176)
Comparing: (    , 41968176) and (   , 41968304)
Comparing: (    , 41968208) and (   , 41968304)
Comparing: (    , 41968240) and (   , 41968304)
Comparing: (, 41968176) and (, 41968272)
Comparing: (, 41968208) and (, 41968272)
Comparing: (, 41968240) and (, 41968272)
Comparing: (, 41968304) and (, 41968272)

SORTED ARRAY
0: (Good, 9)
1: (How r u, 8)
2: (Sup, 2)
3: (Goodbye, 4)
4: (Hello, 1)
Program ended with exit code: 0

1 Ответ

2 голосов
/ 20 марта 2020

Каждый элемент вашего массива - это pair *, но ваша функция сравнения получает анонимные указатели на любые элементы вашего массива, так что в действительности это будет pair **.

. вам нужно разыменовать еще один уровень:

(*(pair**)p1)->value
...