La funzione fscanf permette di leggere tutti i dati di tipo scalare, ossia interi, caratteri e reale. Permette inoltre di leggere stringhe, utilizzando il formato %s. Leggere una stringa in questo modo può a volte portare a risultati che non ci si aspetta: la funzione fscanf, infatti, considera una stringa in input conclusa quando incontra uno spazio.
In alcuni casi può essere necessario leggere invece una intera riga da file. Per questa ragione, è stata introdotta la funzione fgets. L'uso tipico di questa funzione è quello di leggere una intera riga da un file di testo, e poi suddividere questa linea usando la funzione di lettura da stringhe sscanf che si vedrà più avanti. Questa funzione viene anche usata quando una linea in ingresso va considerata come una sola stringa, su cui poi si opera direttamente con le funzioni su stringhe.
La funzione fgets ha tre argomenti: il primo è un vettore di caratteri in cui va memorizzata la linea del file di testo; il secondo è il numero massimo di caratteri che si vogliono mettere in questa stringa; il terzo è un descrittore di file, e indica da quale file si vuole leggere la stringa. Il prototipo di questa funzione è il seguente:
char *fgets(char *s, int size, FILE *fd);
Diamo una descrizione degli argomenti e del valore di ritorno di questa funzione:
Capire quando il file è finito è semplice: basta infatti verificare se il valore risultato vale NULL. Se il risultato è NULL, allora non è stato possibile leggere neanche un carattere. In questo caso, la zona di memoria puntata da s non contiene un valore significativo, per cui non va elaborata.
Esistono ovviamente casi in cui viene letta una linea da file ``ogni tanto'', ma di solito la funzione fgets viene usata per leggere tutto il contenuto di un file riga per riga. Su ogni riga vengono poi fatte delle elaborazioni.
La struttura di un programma di questo genere è: prima si apre il file in lettura (con controllo errori), e poi si entra in un ciclo, in cui si legge una riga a ogni iterazione. In ogni iterazione, si legge una riga, e la si elabora. Se l'operazione di lettura ha dato risultato NULL allora vuol dire che non è stata letta nessuna riga, per cui s non va elaborata, e si deve invece uscire dal ciclo.
Il programma righe.c riportato qui sotto legge un file riga per riga. La elaborazione di una riga è in questo caso semplicemente le sua stampa su schermo. Si noti che la funzione fgets mette nel vettore s tutta la riga letta, incluso il carattere di fine linea. È per questo che la istruzione di stampa usa il formato "%s" invece che "%s\n": infatti, il carattere di andata a capo si trova già nella stringa letta da file.
/* Lettura di un file riga per riga. */ #include<stdlib.h> #include<stdio.h> int main() { FILE *fd; char buf[200]; char *res; /* apre il file */ fd=fopen("righe.txt", "r"); if( fd==NULL ) { perror("Errore in apertura del file"); exit(1); } /* legge e stampa ogni riga */ while(1) { res=fgets(buf, 200, fd); if( res==NULL ) break; printf("%s", buf); } /* chiude il file */ fclose(fd); return 0; }
Si faccia attenzione al fatto che il valore di ritono della funzione fgets (che serve per capire quando il file è finito) è di tipo puntatore a carattere (ossia char *), e non intero come nel caso di fscanf. Questo puntatore non deve ovviamente venire inizializzato.