#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define ARR_LEN(arr) (sizeof(arr) / sizeof(*arr)) #define FILE_END "END" typedef struct { char first_name[64]; char last_name[64]; unsigned int age; } Person; char *fgets_strip(char *s, int size, FILE *stream) { char *ret = fgets(s, size, stream); s[strcspn(s, "\n")] = 0; return ret; } int person_parse(char *s, Person *person) { char format[4 + 1 + 4 + 1 + 2 + 1]; assert((size_t)snprintf( format, ARR_LEN(format), "%%%zus %%%zus %%u", ARR_LEN(person->first_name), ARR_LEN(person->last_name) ) < ARR_LEN(format)); return sscanf( s, format, person->first_name, person->last_name, &person->age ) < 3 ? -1 : 0; } int person_read(FILE *f, Person *person) { char buf[256]; fgets_strip(buf, ARR_LEN(buf), f); if (strncmp(buf, FILE_END, ARR_LEN(FILE_END)) == 0) { return 0; } return person_parse(buf, person) < 0 ? 0 : 1; } void person_print(Person *person) { printf( "nome: %s, cognome: %s, eta': %u\n", person->first_name, person->last_name, person->age ); } int person_is_relative(Person *p1, Person *p2) { return strcmp(p1->last_name, p2->last_name) == 0; } typedef Person Data; typedef struct ListHead { struct ListHead *next; Data data; } ListHead; typedef ListHead *Link; Link list_new_raw(void) { return malloc(sizeof(ListHead)); } Link list_new(Data data) { Link ret = list_new_raw(); ret->data = data; ret->next = NULL; return ret; } Link list_input(FILE *f, int (*input) (FILE *, Data *)) { ListHead *head = NULL; ListHead **next = &head; Data data; while (input(f, &data)) { *next = list_new(data); next = &(*next)->next; } return head; } Link list_find(Link head, Data *key, int (*compare) (Data *, Data *)) { while (head && !compare(key, &head->data)) { head = head->next; } return head; } Link list_find_nth(Link head, Data *key, size_t n, int (*compare) (Data *, Data *)) { size_t count = 0; Link found; while (count < n && (found = list_find(head, key, compare))) { ++count; head = found->next; } return found; } int main(void) { FILE *f = fopen("input.txt", "r"); Link list = list_input(f, person_read); fclose(f); Person key; puts("inserire cognome"); fgets_strip(key.last_name, ARR_LEN(key.last_name), stdin); puts("inserire n"); size_t n; scanf("%zu", &n); Link found = list_find_nth(list, &key, n, person_is_relative); if (found) { person_print(&found->data); } else { puts("il parente ricercato non esiste"); } }