Предполагая, что вам просто нужно знать, какие элементы исходного массива struct
s совпадают, вы можете просто вернуть массив указателей, указывающих на совпадающие элементы. Последняя запись в этом массиве указателей будет содержать NULL
для обозначения конца совпадений.
Таким образом, функция фильтра может выглядеть следующим образом:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Student const ** result_resize(Student const ** result, size_t size)
{
void * pv = realloc((void*) result, size * sizeof *result);
if (NULL == pv)
{
perror("realloc() failed");
exit(EXIT_FAILURE);
}
return pv;
}
Student const ** students_filter_by_name(const char * name, Student * pstudent, size_t size)
{
size_t matches = 0;
size_t size_result = 1;
Student const ** result = result_resize(NULL, size_result);
for (size_t i = 0; i < size; ++i)
{
if (!strcmp(name, pstudent[i].name))
{
if (size_result <= matches)
{
size_result *= 2;
result = result_resize(result, size_result);
}
result[matches] = &pstudent[i];
++matches;
}
}
if (size_result <= matches)
{
++size_result;
result = result_resize(result, size_result);
}
result[matches] = NULL; /* Mark end-of-array */
return result;
}
Используйте это так:
Student const ** students_filter_by_name(
const char * name, Student * pstudent, size_t size);
#define STUDENTS_MAX (42)
int main(void)
{
Student students[STUDENTS_MAX] = {
{"jack", "foo", 1},
{"jill", "bar", 1},
{"alk", "foo", 1},
{"jill", "bar", 1},
{"jack", "foo", 1},
{"alk", "bar", 1},
};
/* Load data to array students here. */
{
const char * name = "alk";
Student const ** ppmatches = students_filter_by_name(
name, students, sizeof students / sizeof *students);
{
Student const ** pploop = ppmatches;
printf("%s's marks:\n", name);
while (pploop && *pploop)
{
printf("subject = '%s', mark = %d\n", (*pploop)->subject, (*pploop)->mark);
++pploop;
}
}
free(ppmatches);
}
}
Чтобы отсортировать результат, просто отсортируйте массив указателей, созданный функцией фильтра.