Lettura e Scrittura di Testo
La libreria standard fornisce diverse funzioni specializzate per leggere e scrivere su stream orientati al testo (come la console o i file .txt).
Scrivere Caratteri e Stringhe
Section titled “Scrivere Caratteri e Stringhe”fputc(c, stream): Scrive un singolo carattere.fputs("Testo", stream): Scrive una stringa, ma a differenza diputs, non aggiunge il ritorno a capo (\n) automaticamente. Spetta a te inserirlo.
FILE *fp = fopen("saluti.txt", "w");if (fp != NULL) { fputs("Ciao mondo!\n", fp); fclose(fp);}Forzare la scrittura: fflush
Section titled “Forzare la scrittura: fflush”Se hai scritto dati in uno stream bufferizzato (es. in un file su disco) ma vuoi costringere il sistema a “svuotare il buffer” salvandoli istantaneamente fisicamente, usa:
fflush(fp);Leggere il testo in modo sicuro: fgets
Section titled “Leggere il testo in modo sicuro: fgets”Come imparato, la funzione gets() è bannata. Per leggere l’input dell’utente o un file riga per riga in totale sicurezza, usa fgets (File Get String).
char buffer[100];// Legge fino a 99 caratteri (lasciando spazio al \0) dallo stream standardfgets(buffer, sizeof(buffer), stdin);fgets smette di leggere quando raggiunge il limite massimo, oppure quando incontra un “A Capo” (\n) o la Fine del File (EOF).
Dati Formattati: fprintf e fscanf
Section titled “Dati Formattati: fprintf e fscanf”Esattamente come printf stampa sulla console, fprintf fa la stessa cosa ma dirige l’output in uno specifico FILE *. È perfetto per generare report testuali.
La funzione simmetrica, fscanf, permette di estrarre dati strutturati (interi, stringhe) analizzando una riga di testo usando i formati (%d, %s, ecc.).
Inoltre offre dei modificatori avanzati chiamati Scanset:
%9s: Legge una stringa di massimo 9 caratteri senza spazi.%99[^\n]: Legge tutto il testo (inclusi gli spazi) fino a quando non trova un a capo (che esclude tramite il caret^), per un massimo di 99 caratteri.
int id;char nome[50];// Mettiamo che il file contenga: "1001 MarioRossi"fscanf(fp, "%d %49s", &id, nome);Best Practice: Parsing Robusto con fgets + sscanf
Section titled “Best Practice: Parsing Robusto con fgets + sscanf”Un difetto di fscanf è che se il testo formattato non corrisponde a ciò che ci aspettiamo, lo stream si “incastra” lasciando caratteri spazzatura nel buffer.
Per applicazioni robuste a livello industriale, la Best Practice assoluta è di leggere un’intera riga grezza in memoria con fgets(), e poi estrarre i dati da quella riga di memoria (non dal file!) usando sscanf().
È vitale controllare il valore di ritorno di sscanf. Questa funzione, infatti, restituisce un intero che indica il numero di campi analizzati con successo e assegnati alle variabili. Se ti aspetti due valori (un nome e un’età), devi assicurarti che sscanf restituisca esattamente 2.
💻 Esercizio Pratico: L’accoppiata Vincente (fgets + sscanf)
Section titled “💻 Esercizio Pratico: L’accoppiata Vincente (fgets + sscanf)”Riceviamo in ingresso stdin una stringa formata da "NOME ETA". Usa prima fgets per leggere in modo sicuro la riga dal buffer, e poi usa un blocco if con sscanf per elaborare i due campi e controllare che il parsing abbia avuto successo.