Проблема с QSORT () - сортировка не выполнена должным образом (C)
Вопрос
У меня есть вопрос относительно QSORT.
Это немного странно, но моя функция QSORT не дает мне правильный выход. Странная вещь состоит в том, что некоторые из моих функций сравнения идентичны моим прошедшим проектам, но они не дают мне правильный ввод вообще. Я не уверен, как проверить это.
Например:
int comp_name_asc(const void *a, const void *b)
{
const Rec *prec1 = (const Rec *) a;
const Rec *prec2 = (const Rec *) b;
return strcmp(prec1->name, prec2->name);
}
int comp_name_desc(const void *a, const void *b)
{
const Rec *prec1 = (const Rec *) a;
const Rec *prec2 = (const Rec *) b;
return strcmp(prec2->name, prec1->name);
}
Вторая функция должна быть порядок убывания, но результат идентичен: она всегда в порядке возрастания. Я проверил, чтобы убедиться, что правильная функция вводится в нужное время. REC - это тип для структуры, который я сделал, который имеет параметр имени Char *.
Также (изменено, чтобы избежать переполнения):
int comp_size_asc(const void *a, const void *b)
{
const Rec *prec1 = (const Rec *) a;
const Rec *prec2 = (const Rec *) b;
if (prec1->byteSize > prec2->byteSize)
return 1;
else if (prec1->byteSize < prec2->byteSize)
return -1;
else
return 0;
}
Результатом совершенно странный, не возрастающий или нисходящий (т. Е. 500, 515, 100, 200 ...). Bytesize имеет тип OFF_T, полученный путем выполнения:
char *path; // Build the path
struct stat sb;
if (lstat(path, &sb) == 0) {
// Read sb.st_size
Я действительно не уверен, как отладить это. Все, что я знаю, это то, что введена соответствующая функция сравнения, и что некоторые подобные функции сравнения, используемые для работы в прошлом.
Любые идеи или как я могу отладить, это будет приветствоваться. Спасибо.
РЕДАКТИРОВАТЬ:
Добавление звонка в QSORT:
int index = 0;
Rec **array = (Rec **) malloc(sizeof(Rec *) * capacity);
// Adds element to the array...
qsort(array, index, sizeof(Rec *), comp_name_desc);
(Каждый раз, когда элемент добавляется в массив, индекс увеличивается.)
Спасибо.
РЕДАКТИРОВАТЬ:
Решение было дано ниже. Благодарю вас!
Я должен был измениться:
const Rec *prec1 = (const Rec *) a;
к
const Rec *prec1 = *(const Rec **) a;
Из -за того, как я определил свой массив. Спасибо!
Решение
У вас есть массив Rec
, или, скорее, массив Rec
указатели? Я спрашиваю, потому что функция сравнения получает в качестве указателей параметров в массиве, а не непосредственно в ваши записи.
Вот демонстрация обоих способов:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Rec {
char *name;
} Rec;
/*
* The pointers a and b point directly into the array,
* where the Records themselves are.
*/
static int
cmp_Rec_by_name(const void *a, const void *b) {
const Rec *rec1 = (Rec *)a;
const Rec *rec2 = (Rec *)b;
return strcmp(rec1->name, rec2->name);
}
/*
* The pointers point directly into the array, where
* not the records but pointers to them are. So they
* are a pointer to a pointer to a record.
*/
static int
cmp_Rec_ptr_by_name(const void *a, const void *b) {
const Rec *rec1 = *(Rec **)a;
const Rec *rec2 = *(Rec **)b;
return strcmp(rec1->name, rec2->name);
}
static void
sort_Rec(void) {
Rec record[3];
record[0].name = strdup("hello");
record[1].name = strdup("world");
record[2].name = strdup("how are you");
qsort(record, 3, sizeof (Rec), cmp_Rec_by_name);
for (int i = 0; i < 3; i++)
printf("%s\n", record[i].name);
}
static void
sort_Rec_ptr(void) {
Rec *(record[3]);
record[0] = malloc(sizeof (Rec));
record[1] = malloc(sizeof (Rec));
record[2] = malloc(sizeof (Rec));
record[0]->name = strdup("hello");
record[1]->name = strdup("world");
record[2]->name = strdup("how are you");
qsort(record, 3, sizeof (Rec *), cmp_Rec_ptr_by_name);
for (int i = 0; i < 3; i++)
printf("%s\n", record[i]->name);
}
int
main() {
sort_Rec();
sort_Rec_ptr();
return 0;
}
Другие советы
Вы никогда не должны сравнивать цифры, вычитая один из другого. Это, как правило, приведет к переполнению с подписанными типами и вообще не будет работать с без знаки. Общая идиома для сравнения номеров с результатом TRI-состояния является следующим
(a > b) - (a < b)
В противном случае ваши функции сравнения выглядят нормально, поэтому проблема должна быть в том, как вы вызываете функцию сортировки.
Услышать, что такое поведение, догадка может быть, что имена на самом деле не являются именами, если strcmp()
У меня были обменены два аргумента, и результаты все еще поднимаются. Одно предложение может быть распечатано имена, используя printf
, А также уменьшить имена до 2 или 3 (количество записей), чтобы облегчить отладку и проверку, почему он ведет себя так.