Gestione dei File

OBIETTIVO DELLA LEZIONE
Comprendere gli utilizzi dei file nella programmazione. Essere in grado di aprire, scrivere, leggere e chiudere correttamente un file all'interno dei programmi. In particolare:
    Introduzione all'uso dei file
  1. Comprendere il significato l'uso dei file nella programmazione
  2. Comprendere che tutte le operazioni di Input/Output e la gestione dei file vengono trattati in C attraverso lo stesso formalismo: lo stream
  3. Comprendere e distinguere il concetto di accesso sequenziale e casuale ad un file

    Programmi per la gestione dei file
  4. Essere in grado di scrivere semplici programmi impieganti file
  5. Approfondire gli aspetti delle operazioni riguardanti i file mediante esempi di codice

    Programma per la gestione di una agenda
  6. Essere in grado di impiegare i file all'interno di programmi complessi
  7. Essere in grado di passare alle funzioni le informazioni riguardanti i file
.:. LUCIDI DELLA LEZIONE .:.
.:. NOTE DELLA LEZIONE .:.

Lab

Prima di iniziare

Rileggi velocemente i lucidi della lezione di stamattina. I costrutti presentati saranno molto utili per risolvere gli esercizi di oggi.

Esercizio 1 (Ripasso teoria Gestione dei File)
Prova a rispondere alle seguenti domande.
Se non trovi le risposte o non sei sicuro, rivedi la lezione.
--------------------------------------------------------------------------------
1. La funzione fscanf non può essere usata per leggere i dati dallo standard input:

vero
falso

--------------------------------------------------------------------------------
2. Tutti i file devono essere aperti prima di essere letti o scritti, per questo motivo 
stdin, stdout e lo standard error devono essere aperti con una fopen prima di essere usati:

vero
falso

--------------------------------------------------------------------------------
3. Tutti i file devono essere chiusi prima della uscita dal main con fclose:

vero
falso

--------------------------------------------------------------------------------
4. Per trovare un record in un file ad accesso casuale non è necessario scorrere tutti 
gli altri record nel file

vero
falso

--------------------------------------------------------------------------------
5. La funzione fseek deve essere usata solo per trovare l'inizio del file:

vero
falso

Esercizio 2: Programmi per la gestione dei file (ripasso sintassi lettura/scrittura e regole)
Prova a scrivere su carta le soluzioni ai quesiti elencati, immaginando che le istruzioni lanciate siano in sequenza (es. se modifichi un puntatore esso rimarrà in memoria a disposizione delle successive istruzioni):
  1. scrivi un'istruzione che apra in LETTURA il file testo.dati e assegni alla variabile puntatore a file ptesto il puntatore ottenuto;
  2. scrivi un'istruzione che apra in SCRITTURA e CREAZIONE il file nuovotesto.dati e assegni alla variabile puntatore a file ptestonuovo il puntatore ottenuto;
  3. scrivi un'istruzione che LEGGA un RECORD dal file testo.dati. Il record sarà formato da un intero, una stringa e un valore in virgola mobile. I valori letti devono essere memorizzati rispettivamente nelle variabili numeroConto, nome, euroSulConto;
  4. scrivi un'istruzione che SCRIVA un RECORD dal file testo.dati. Il record sarà formato da un intero, una stringa e un valore in virgola mobile. I valori letti devono essere memorizzati rispettivamente nelle variabili numeroConto, nome, euroSulConto.

soluzione.
Esercizio 3: Creazione di un file
Scrivi il programma magia.c sviluppando le attività elencate:
  1. crea un file magia.txt: se esso non esiste devi crearlo; se invece esiste cancella tutto il suo contenuto ed inizia a scrivere dall'inizio;
  2. scrivi nel file la parola "abracadabra";
  3. chiudi il file.
Per verificare la correttezza del programma che hai editato controlla cosa accade se:
  1. nella directory corrente vi è già un file che si chiama magia.txt;
  2. il file magia.txt esiste e contiene più caratteri della stringa "abracadrabra" e se ne contiene meno;
  3. il file magia.txt è vuoto;
  4. il file magia.txt non esiste.

soluzione.
Esercizio 4: Scrittura stringhe nei file
Scrivi il programma magia2.c sviluppando le attività elencate:
  1. crea un file magia.txt: se esso non esiste devi crearlo; se invece esiste cancella tutto il suo contenuto ed inizia a scrivere dall'inizio;
  2. chiede all'utente una stringa e la salva nel file;
  3. chiude il file.
Per verificare la correttezza del programma che hai editato controlla cosa accade se:
  1. l'utente immette la stringa "abracadabra";
  2. l'utente immette la stringa "metto degli spazi".
Presta attenzione a ciò che troverai nel file magia.txt dopo aver lanciato il programma e cerca di comprendere i motivi di ciò che vedrai.

Suggerimento
Leggi il file di help della scanf e verifica cosa intende per stringa la scanf: dalla nota potrai comprendere perché il tuo file contiene solo alcuni caratteri e non tutti quelli che ti saresti aspettato.

soluzione.
Esercizio 5: Come salvare dei campi in un file di testo
Sviluppa le seguenti attività passo dopo passo:
  1. salva nel file di testo campi1.txt quanto di seguito riportato (N.B: poni attenzione ai ritorni a capo):
    Alberto
    Massimo
    Veronica
    Giovanni
  2. salva nel file di testo campi2.txt quanto di seguito riportato (N.B: per separare i campi usa SOLO DEGLI SPAZI):
    Alberto Massimo Veronica Giovanni
  3. salva nel file di testo campi3.txt quanto di seguito riportato (N.B: per separare i campi usa SOLO IL TASTO DI TABULAZIONE ):
    Alberto    Massimo    Veronica    Giovanni 
  4. scrivi il programma leggiCampi.c che soddisfi le seguenti specifiche:
    1. apre in LETTURA il file campi1.txt ;
    2. se il file non esiste ritorna un messaggio di errore e termina;
    3. stampa a monitor tutti i campi leggendoli dal file (il programma deve funzionare correttamemnte con tutti e tre i file).
Prova con i file campi1.txt, campi2.txt, campi3.txt: il programma si comporta diversamente? Perchè?
soluzione.
Esercizio 6: programma per la gestione di una rubrica
Considera la traccia di codice sotto riportata:
  1. il file rubrica.txt viene aperto, chiuso e riaperto. Modifica opportunamente la traccia di codice in modo che il file rubrica.txt venga aperto in lettura/scrittura una sola volta;
  2. salva il programma con il nome EsaminaFiles2.c.
    // questo programma vi fa familiarizzare con le
    // strutture dati dei FILE (cosa e' un puntatore a file)
    // scrive in un file in modalita' append
    // legge da un file dall'inizio fino all'ultima sua stringa
    #include <stdio.h>
    
    int main()
    {
    	char nome[256], cognome[256], tel[256];
    	char finito;
     	char nomefile[]="rubrica.txt"	;
    	FILE *Fp1;
    
    	// Apro il file in modalita' append testo
    	Fp1 = fopen(nomefile, "a");
    	if (Fp1==NULL){
    		printf("File %s not found\n", nomefile);
    		exit(-1); 
    	}
    	printf("Il puntatore (*Fp) al file %s e' %d\n\n", nomefile, Fp1);
    	
    	finito='n';
    	while((finito=='n') || (finito=='N'))
    	{
    		printf("Inserire Nome: "); scanf("%s", nome);
    		printf("Inserire Cognome: "); scanf("%s", cognome);
    		printf("Inserire TEL: "); scanf("%s", tel); 
    
    		fprintf(Fp1, "%s\t%s\t%s\n", nome, cognome, tel);
    		fflush(stdin);
    
    		printf("Finito? S(i) oppure N(o) --> ");
    		scanf("%c", &finito);
    	}
    	
    	// chiudo il file  e lo riapro in lettura testo
    	fclose(Fp1);
    	Fp1 = fopen(nomefile, "r");	
     	if (Fp1==NULL){
    		printf("File %s not found\n", nomefile);
    		exit(-1); 
    	}
    	
    	// il puntatore della posizione corrente del file e' all'inizio
    	// (il file e' stato appena aperto), quindi lo leggeremo dall'inizio
    	// IDEA: continuo a leggere con la stessa maschera con cui ho
    	// scritto fino a che la fscanf assegna il numero di campi corretto
    	printf("\n\nRubrica:\n");
    	while ( fscanf(Fp1, "%s\t%s\t%s\n", nome, cognome, tel) == 3 ) 
    	{
    		printf("%s %s, %s\n", nome, cognome, tel);
    	}
    	close(Fp1);   // mi ricordo di chiudere il file 
    
    	fflush(stdin);
      	getchar(); 
          
          exit(0);
    }
    

Suggerimento
Per evitare che il file rubrica.txt venga aperto in lettura/scrittura, riposiziona la testina di lettura all'inizio del file con la funzione fseek() o con la funzione rewind(). Se hai incontrato errori durante la fase di scrittura nel tuo codice, controlla se ti sei ricordato anche di cambiare la modalità di apertura del file in "a+".

Se non riesci a scrivere il programma richiesto rivedi tutte le attività precedenti (con riferimento alla lezione in oggetto).

soluzione.
Esercizio 7: Scrivere una tabella di dati in un file
Con riferimento alle funzioni utilizzate per aprire, gestire e chiudere un file di testo, prova ora a scrivere il programma scrivitabella.c che crea il file temperature.txt in cui su ogni riga sono presenti il nome di una città e la relativa temperatura, separati da una tabulazione.

Considera inoltre i seguenti requisiti:
- le città e le temperature vengono immesse dall'utente;
- l'utente può inserire solo quattro città.

Suggerimento
La traccia di codice presentata nel precedente esercizio ha già la struttura necessaria per risolvere questo esercizio: basta modificare la parte delle scanf. Se non riesci a scrivere il programma richiesto rivedi tutte le attività precedenti (con riferimento alla lezione in oggetto).

soluzione.
Esercizio 8:
Basandoti sul programma scrivitabella.c che hai costruito nel precedente esercizio, modifica il codice in modo che l'utente possa inserire tutte le città che desidera (invece di quattro solamente). Usa come condizione di terminazione del ciclo il carattere zero (tasto dello zero).
Salva il programma modificato con il nome scrivitabella2.c

Suggerimento
Se usi un ciclo di lettura da tastiera che legge STRINGHE, anche il carattere zero (tasto con scritto sopra zero) verrà letto come stringa, ossia '0' più il terminatore. E' possibile controllare se il primo carattere di una stringa è '0' nel seguente modo:
if (stringa[0] == '0')
Se non riesci a scrivere il programma richiesto rivedi tutte le attività precedenti (con riferimento alla lezione in oggetto).

soluzione.
Esercizio 9: Conteggio caratteri nella costituzione Italiana
Scrivi un programma che:
  1. conta quanti caratteri ci sono nel file COSTITUZ.TXT (63 KB) : è possibile contarli direttamente oppure usare la funzione fseek();
  2. conta quante volte compare la lettera 'r' (maiuscola o minuscola);
  3. calcola come FLOAT la frequenza di occorrenza della lettera 'r' (è indifferente se maiuscola o minuscola);
  4. (facoltativo) riscrivi il codice che trova quale è la lettera più ripetuta nel file costituz.txt: puoi fare una versione elementare che conta tutte le lettere contenute nel file in oggetto, oppure una versione più avanzata che considera che i caratteri, nel linguaggio C, sono numeri crescenti.

soluzione.
Esercizio 10: Cercare una stringa in un file di testo
Con riferimento al testo sotto riportato, sviluppa le seguenti attività:
  1. salva il testo nel file frank.txt;
  2. accedi al file frank.txt e trova quante volte compare la parola "the" ;
  3. individua la lettera più ripetuta.
Beaufort had taken effectual measures to conceal himself; and it was ten months 
before my father discovered his abode. Overjoyed at this discovery, he hastened to 
the house, which was situated in a mean street, near the Reuss. But when he entered, 
misery and despair alone welcomed him. Beaufort had saved but a very small sum of 
money from the wreck of his fortunes; but it was sufficient to provide him with 
sustenance for some months, and in the meantime he hoped to procure some respectable 
employment in a merchant's house. The interval was, consequently, spent in inaction; 
his grief only became more deep and rankling when he had leisure for reflection; and 
at length it took so fast hold of his mind that at the end of three months he lay on 
a bed of sickness, incapable of any exertion. 

His daughter attended him with the greatest tenderness; but she saw with despair 
that their little fund was rapidly decreasing, and that there was no other prospect 
of support. But Caroline Beaufort possessed a mind of an uncommon mould; and her 
courage rose to support her in her adversity. She procured plain work; she plaited 
straw; and by various means contrived to earn a pittance scarcely sufficient to 
support life. 

Suggerimento
Come hai avuto modo di vedere il file viene scandito. Il confronto fra stringhe può essere eseguito nei seguenti modi:
  1. usando la funzione strcmp() presente nella libreria string.h (la documentazione di strcmp() contiene esempi di utilizzo);
  2. confrontando tutti i caratteri uno alla volta.

soluzione.




Informazioni sul sito