Sottrazione fra file

Lo scopo di questo esercizio è quello di leggere due file che contengono degli interi, e scrivere un file che contiene le differenza fra elementi del primo e del secondo.

Per essere più precisi, i due file contengono ognuno una sequenza di numeri interi. Supponiamo che i nomi di questo due file siano uno e due. Si vuole fare in modo che il file risultato, di nome ris, contenga anch'esso una sequenza di interi, di cui il primo è ottenuto facendo la sottrazione fra il primo intero di uno e il primo intero di due. Il secondo intero deve essere ottenuto per sottrazione fra il secondo di uno e il secondo di due, ecc.

Questo esercizio si potrebbe risolvere usando i vettori, ossia leggendo tutti gli interi del primo file e mettendoli in un vettore, e lo stesso per il secondo file. Facendo la sottrazione elemento per elemento, e scrivendo il risultato su file, si ottiene il risultato voluto

Vediamo ora una soluzione che non usa vettore, ed è quindi più efficiente come occupazione di memoria. Usiamo questo algoritmo: dopo aver aperto i due file, leggiamo un intero dal primo file e uno dal secondo; facciamo la sottrazione e scriviamo il risultato sul terzo file.

Per implementare questo algoritmo, dobbiamo aprire tutti e tre i file, i primi due in lettura e il terzo in scrittura. Infatti, per poter accedere a un file, occorre prima aprirlo. Le successive operazioni di lettura e scrittura usano il valore del descrittore di file per capire su quale file occorre leggere o scrivere. Quindi, ci servono tre variabili per memorizzare i tre descrittori di file che si ottengono dall'apertura dei tre file.

Definiamo quindi le tre variabili:

  FILE *piu, *meno, *out;

Quando apriamo il primo file, assegnamo a piu il risultato della apertura del file uno, ossia il descrittore di questo file. Facendo lo stesso per gli altri file, le tre variabili piu, meno e out possono venire usate per dire alle funzioni fscanf e fprintf su quali file operare. Per esempio, per leggere un intero dal file uno passiamo a fscanf il descrittore del primo file, cioè piu:

  fscanf(piu, "%d", &x);

Il programma completo sottrai.c è riportato qui sotto. Quando uno dei due file di input (piu e meno) è terminato, si smette di leggere e si chiudono tutti e tre i file. Quindi, il terzo file contiene un numero di interi che è il minimo fra il numero di elementi del primo e del secondo file.

/*
  Sottrae, elemento per elemento, il contenuto
di due file
*/

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

int main() {
  FILE *piu, *meno, *out;
  int x, y;
  int res;


		/* apre il primo file in lettura */
  piu=fopen("piu", "r");
  if( piu==NULL ) {
    perror("Errore in apertura del primo file");
    exit(1);
  }


		/* apre il secondo file in lettura */
  meno=fopen("meno", "r");
  if( meno==NULL ) {
    perror("Errore in apertura del secondo file");
    exit(1);
  }


		/* are il file in scrittura */
  out=fopen("ris", "w");
  if( out==NULL ) {
    perror("Errore in apertura del file risultato");
    exit(1);
  }


		/* legge i file */
  while(1) {
    res=fscanf(piu, "%d", &x);
    if( res!=1 )
      break;

    res=fscanf(meno, "%d", &y);
    if( res!=1 )
      break;

    fprintf(out, "%d\n", x-y);
  }


		/* chiude i file */
  fclose(piu);
  fclose(meno);
  fclose(out);

  return 0;
}

La cosa importante da notare in questo programma è che è possibile avere più file aperti contemporaneamente: in questo caso, i due file in lettura e il file in scrittura restano aperti contemporaneamente. Per dire alle funzioni fscanf e fprintf quale è il file da cui devono leggere o scrivere, si usa il descrittore di file.