Lettura e scrittura in sequenza

Le operazioni di lettura e scrittura fscanf e fprintf hanno un comportamento simile alle funzioni scanf e printf con la differenza che la lettura e scrittura avviene da file invece che da tastiera/schermo.

Questa regola permette di capire il comportamento delle funzione fscanf e fprintf in situazioni più complesse. Cosa succede per esempio se si fanno due operazioni fscanf(fd, "%d", &x) l'una dopo l'altra? Basta pensare cosa succederebbe se al posto della fscanf ci fosse una scanf. L'effetto sarebbe quello di leggere due interi, l'uno dopo l'altro, da tastiera. Dal momento che stiamo invece usando la fscanf, facciamo la stessa cosa ma leggendo da file. Quindi, si leggono due interi, l'uno dopo l'altro, dal file il cui descrittore è fd.

È come se le operazioi di lettura avvenissero da tastiera invece che da file, e sulla tastiera venisse digitato il contenuto del file. Quindi, dopo che si è letto qualcosa, la successiva operazione di lettura legge quello che segue sul file. In altre parole, due operazioni fscanf in sequenza non leggono la stessa cosa: la seconda legge quello che resta sul file dopo aver letto la prima.

Il programma leggidue.c è un programma in cui c'è una sequenza di due operazioni di lettura da file.

/*
  Legge due interi da file
*/

#include<stdlib.h>
#include<stdio.h>

int main() {
  int x, y;
  FILE *fd;

  		/* apre il file */
  fd = fopen("dueinteri.txt", "r");
  if( fd==NULL ) {
    perror("Errore in apertura del file");
    exit(1);
  }


		/* legge il primo intero */
  fscanf(fd, "%d", &x);


		/* legge il secondo intero */
  fscanf(fd, "%d", &y);


		/* chiude il file */
  fclose(fd);


		/* stampa i due interi */
  printf("Ho letto %d e %d\n", x, y);

  return 0;
}

La prima cosa che avviene eseguendo questo programma è che il file viene aperto in lettura. Dopo il controllo se l'apertura ha avuto successo, viene letto un intero con la istruzione fscanf(fd, "%d", &x). La successiva operazione è ancora una istruzione di lettura da file fscanf(fd, "%d", &y). Da notare che questa seconda operazione non legge lo stesso intero della prima. Al contrario, viene letto il secondo intero che si trova su file (se c'è). Per provare questo programma, occorre creare un file di testo di nome dueinteri.txt, in cui vanno scritti due numeri interi.

Per quello che riguarda la scrittura su file, questa avviene sempre in modo consecutivo. Dopo che si è scritto qualcosa usando fprintf, le successive operazioni di scrittura scrivono di seguito. In altre parole, se si usa due volte di seguito la fprintf, la due cose scritte su file appaiono l'una di seguito all'altra. Il programma seguente scrividue.c scrive un intero su file con l'istruzione fprintf(fd, "%d ", x). La successiva istruzione di stampa su file fprintf(fd, "%d ", y) scrive un secondo intero di seguito al primo. L'effetto complessivo è che sul file vengono scritti i due numeri di seguito.

/*
  Scrive due interi da file
*/

#include<stdlib.h>
#include<stdio.h>

int main() {
  int x, y;
  FILE *fd;

  x=-10;
  y=21;

  		/* apre il file */
  fd = fopen("dueinteri.txt", "w");
  if( fd==NULL ) {
    perror("Errore in apertura del file");
    exit(1);
  }


		/* scrive il primo intero */
  fprintf(fd, "%d ", x);


		/* scrive il secondo intero */
  fprintf(fd, "%d ", y);


		/* chiude il file */
  fclose(fd);

  return 0;
}

Si noti che, per essere sicuri di avere uno spazio di separazione fra i due interi, occorre metterlo esplicitamente. È per questo che la stringa di formato della prima istruzione di stampa è "%d " con uno spazio in fondo, invece che "%d". In questo secondo caso, i due interi sarebbero stati scritti su file consecutivamente, ossia senza spazi in mezzo. Questo avrebbe prodotto un file con contenuto -1021, senza spazi fra i due numeri. Un file con questo contenuto viene di solito interpretato come un file che contiene un solo numero intero di valore -1021. Questo è anche quello che si ottiene leggendo un intero da file usando la funzione fscanf. Si può quindi dire che non mettere spazi fra due interi quando di scrivono su file è un errore.