Oltre al problema evidenziato dal nostro ottimo Oregon, c'è anche un macroscopico errore di engineering.
Il formato scelto per la memorizzazione nel file è forse adatto per un report o una presentazione su schermo, ma è del tutto inefficiente e comporta una ridondanza del tutto inutile (i nomi dei campi ripetuti per ogni record!), che inevitabilmente poi ti complicherà la vita in fase di rilettura.
Per un file del genere, considerando anche che si tratta di un esercizio, va benissimo l'uso di ASCII ma devi assolutamente usare le convenzioni dei più semplici file delimited (CDF ossia comma-delimited file):
1) Un record su ogni "riga", quindi si usa un solo '\n' al termine;
2) Campi separati da un simbolo convenzionale, i più gettonati sono ',' e ';';
3) Stringhe (campi) singolarmente delimitate da virgolette semplici o doppie (meglio).
Peraltro, è assolutamente opportuno raggruppare tutte le fprintf() in un singolo statement a valle degli input, sia per massimizzare l'efficienza che per coerenza logica.
fprintf(fd, "\"%s\";\"%s\";\"%s\";\"%s\";\"%s\";\"%s\"\n",
a[k].nick,
a[k].nomecognome,
a[k].contatto,
a[k].dataora,
a[k].titolo;
a[k].descrizione);
Volendo si può anche organizzare il file per colonne a larghezza fissa, ciascuna corrispondente ad un campo, in puro stile stegosauro COBOL o simili, sempre restando al confine tra il report human-readable e la memorizzazione su file vera e propria.
Potrebbe essere utile, inoltre, assegnare un numero strettamente sequenziale (senza andar troppo per il sottile con eventuali cancellazioni) ad ogni "annuncio", memorizzandolo ad inizio riga.