
Originariamente inviata da
M.A.W. 1968
Mi corre l'obbligo di sottolineare che il codice (peraltro presentato su vari forum in contemporanea) contiene molti altri gravissimi errori di progettazione, di stile e di implementazione. Sfortunatamente non c'è tempo di analizzarli nel dettaglio, quindi procediamo con alcuni esempi in ordine sparso.
codice:
#define CLEAR_BUFFER do { c = getchar(); } while (c != '\n' && c != EOF);
è un tipico errore che, secondo il livello dell'esame, può comportare la
bocciatura o nel migliore dei casi un drastico abbassamento della valutazione. In contesti di programmazione normali, non si deve assolutamente e
in alcun caso "nascondere" il terminatore di statement del C entro una macro, né tantomeno includervi variabili che saranno poi, forse, chissà come e chissà dove dichiarate. Non siamo all'IOCCC, e il purging del buffer di tastiera può e deve avvenire entro una normalissima funzione C.
Il modo in cui viene usata la realloc() è poi inaccettabile. Premesso che l'array di strutture è la struttura dati
meno indicata per la gestione di una simile implementazione (ma questa scelta può dipendere da vincoli e imposizioni didattiche, quindi non approfondiamo), l'acquisizione delle stringhe da tastiera un carattere per volta con chiamate reiterate alla realloc() è davvero oltre i confini della fantascienza.
In casi del genere, l'idioma più solido e fondamentale prevede di:
1) Allocare staticamente nello heap un buffer di adeguate dimensioni (
vulgo, prima del main());
2) Accettare l'input utente in tale buffer, usando esclusivamente una fgets() su stdin (la scanf è deprecatissima per l'input di stringhe);
3) Allocare dinamicamente, se proprio se ne ha voglia, un buffer di dimensione pari alla lunghezza della stringa appena immessa (i.e. strlen()). Tale puntatore, una volta verificatane la corretta allocazione (i.e. non NULL) sarà associato al puntatore di campo nella struttura corrente, corrispondente al nuovo record.
4) Copiare il contenuto del buffer di lavoro nel buffer di campo appena allocato.
Vi sono poi molti altri aspetti secondari (es. le chiamate alla printf() sono molto costose computazionalmente, e conviene sempre aggregarle o evitarne l'uso in favore di puts ovunque possibile), ma per il momento potremmo fermarci qui.