Как сделать сортировку qsort структуры по элементу поля, которое является массивом целых чисел на Си?
У меня есть структура человека и ввод 12 таких человек с клавиатуры.
typedef struct
{
char surname[30];
char name[20];
char znak_zodiaka[10];
int birthday_date[3];
}znak;
...
znak znaks[12];
Нужно отсортировать этих людей по дате рождения по возрастанию (если годы равны, сравнивать месяцы, а если и они равны, то сравнивать дни). Для даты рождения есть в структуре массив int birthday_date[3], в который записывалась информация в виде день.месяц.год.
Я понимаю, что нужно сделать qsort(znaks, 12, sizeof(znak), compare_age), но как реализовать сам компаратор compare_age?
Я пробовала так
int compare_age(const void* a, const void* b)
{
znak* znak_a = (znak*)a;
znak* znak_b = (znak*)b;
if (znak_a->birthday_date[2] > znak_b->birthday_date[2])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[2] < znak_b->birthday_date[2])
return (znak_a->birthday_date - znak_b->birthday_date);
else
{
if (znak_a->birthday_date[1] > znak_b->birthday_date[1])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[1] < znak_b->birthday_date[1])
return (znak_a->birthday_date - znak_b->birthday_date);
else
{
if (znak_a->birthday_date[0] > znak_b->birthday_date[0])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[0] <= znak_b->birthday_date[0])
return (znak_a->birthday_date - znak_b->birthday_date);
}
}
}
Но сортировка идет неверно. Полный код
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <windows.h>
#include <math.h>
#define LEN 12
typedef struct
{
char surname[30];
char name[20];
char znak_zodiaka[10];
int birthday_date[3];
}znak;
int compare_age(const void* a, const void* b)
{
znak* znak_a = (znak*)a;
znak* znak_b = (znak*)b;
if (znak_a->birthday_date[2] > znak_b->birthday_date[2])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[2] < znak_b->birthday_date[2])
return (znak_a->birthday_date - znak_b->birthday_date);
else
{
if (znak_a->birthday_date[1] > znak_b->birthday_date[1])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[1] < znak_b->birthday_date[1])
return (znak_a->birthday_date - znak_b->birthday_date);
else
{
if (znak_a->birthday_date[0] > znak_b->birthday_date[0])
return (znak_b->birthday_date - znak_a->birthday_date);
else if (znak_a->birthday_date[0] <= znak_b->birthday_date[0])
return (znak_a->birthday_date - znak_b->birthday_date);
}
}
}
int main(void)
{
/*Для русифицирования символов*/
setlocale(LC_ALL, "RUS");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
znak znaks[LEN];
char buf[100];
int col_mans = 0;
for (int i = 0; i < LEN; i++)
{
printf("\t\t\tЧеловек № %d\n", i+1);
printf("Введите фамилию: (Если хотите прервать ввод, введите \"!\"\") ");
scanf_s("%s", buf, 100);
/*Прерывание*/
if (strstr(buf, "!") != NULL) break;
strcpy(znaks[i].surname, buf);
printf("\nВведите имя: ");
scanf_s("%s", buf, 100);
strcpy(znaks[i].name, buf);
printf("\nВведите знак зодиака: ");
scanf_s("%s", buf, 100);
strcpy(znaks[i].znak_zodiaka, buf);
printf("\nВведите дату рождения через пробел [дд мм гггг]: ");
scanf_s("%d %d %d", &(znaks[i].birthday_date[0]), &(znaks[i].birthday_date[1]), &(znaks[i].birthday_date[2]));
col_mans++;
}
printf("\n\n\n\t\t\tРезультаты без сортировки\n");
for (int i = 0; i < col_mans; i++)
{
printf("\t\t\tЧеловек № %d\n", i+1);
printf("Фамилия: %s\nИмя: %s\nЗнак зодиака: %s\nДата рождения: %02d.%02d.%02d\n", znaks[i].surname, znaks[i].name, znaks[i].znak_zodiaka, znaks[i].birthday_date[0], znaks[i].birthday_date[1], znaks[i].birthday_date[2]);
}
qsort(znaks, col_mans, sizeof(znak), compare_age);
printf("\n\n\n\t\t\tРезультаты с сортировкой по дате рождения (возрастание)\n");
for (int i = 0; i < col_mans; i++)
{
printf("\t\t\tЧеловек № %d\n", i + 1);
printf("Фамилия: %s\nИмя: %s\nЗнак зодиака: %s\nДата рождения: %02d.%02d.%02d\n", znaks[i].surname, znaks[i].name, znaks[i].znak_zodiaka, znaks[i].birthday_date[0], znaks[i].birthday_date[1], znaks[i].birthday_date[2]);
}
return 0;
}
Источник: Stack Overflow на русском