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.