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.