La funzione fgets è molto utile quando un file di testo va elaborato una linea per volta. Esistono dei casi in cui non è da sola sufficiente. Consideriamo per esempio il caso in cui si vuole leggere da file degli interi, ignorando le linee che iniziano con un carattere '#'. In questo caso, per saltare le linee che iniziano con '#' la funzione fgets risulta comoda, mentre per leggere degli interi la funzione fscanf è la scelta migliore. Il problema è che, una volta letta una linea da file con fgets, se si cerca di fare una lettura con fscanf quello che si legge è il seguito del file, ossia la linea letta da fgets non viene poi scandita di nuovo da fscanf.
Una delle funzioni di libreria del C che risulta utile in questi casi è la funzione di lettura da stringa (esistono molte altre situazioni in cui questa funzione può essere utile). Questa funzione si chiama sscanf, e ha gli stessi argomenti della fscanf tranne il primo, che è una stringa invece che un descrittore di file. Questa funzione legge i dati dalla stringa invece che da file, ma per il resto il comportamento è identico.
Il seguente programma mediacommenti.c è un esempio di uso di questa funzione: si legge un file di testo, in cui le linee che iniziano con il carattere '#' sono commenti, mentre le altre linee contengono due numeri interi ciascuna.
/* Calcola la media degli interi su file. Le linee che iniziano con # sono commenti e non vengono considerate. */ #include<stdlib.h> #include<stdio.h> int main() { FILE *fd; char buf[200]; char *res; int x, y; int n, somma, media; /* apre il file */ fd=fopen("mediacommenti.txt", "r"); if( fd==NULL ) { perror("Errore in apertura del file"); exit(1); } /* legge una riga per volta */ somma=0; n=0; while(1) { res=fgets(buf, 200, fd); if( res==NULL ) break; if( buf[0]!='#' ) { sscanf(buf, "%d %d", &x, &y); somma+=(x+y); n+=2; } } /* stampa la media */ printf("La media e' %d\n", somma/n); return 0; }
Un possibile miglioramento di questo programma è il controllo che le linee che non sono commenti contengono effettivamente due interi. Questo controllo si può fare tenendo conto che il valore di ritorno della funzione sscanf è lo stesso valore che avrebbe fscanf se la stringa fosse il contenuto di un file.