Tutorato Elementi di Informatica 2019
Università degli Studi di Cagliari
Pattern Recognition & Application Lab
Dipartimento di Ingegneria Elettrica
ed Elettronica
Mail: [email protected]: bioinfo18
Esercitazione 7
I File
28 Novembre 2019
Marco Micheletto
Introduzione ai file
E’ un particolare tipo, che serve ad identificare appunto I/O diverso da “standard I/O” .
• Un file può essere una sorgente di stream (come la tastiera con scanf)
• Un file può essere una destinazione di stream (come il video con printf)
Per utilizzare un file è si usa una struttura dati (struct) che ha tipo FILE (in maiuscolo). Perciò sidefinisce:
FILE *fp;
una variabile di tipo puntatore a FILE (file pointer) per memorizzare l’indirizzo della strutturaFILE associata al file FILE *variabile;
Introduzione ai file
Apertura di un file
La funzione fopen apre un file, crea e riempie la struttura FILE da associaread esso.
• nome è una stringa (costante o variabile) contenente il nome del file e
l’eventuale percorso.
• modo è una stringa indicante la modalità di apertura del file (lettura o
scrittura)
• "r" – sola lettura (read), il file deve già esistere
• "w" – sola scrittura (write), crea vuoto il file da scrivere; se esiste già, lo
elimina e lo ricrea nuovo (quindi se ne perde il contenuto)
• "a" – sola scrittura (append), se non esiste viene creato nuovo e vuoto, se
invece esiste NON viene cancellato e i dati vengono aggiunti al fondo di
quelli già presenti
fp=fopen(nome, modo);
Introduzione ai file
Quizzzzzz 3
Un primo esempio. Cosa fa questo frammento di codice?
1. Crea un puntatore a FILE, apre/crea un file di nome esempio.txt inmodalità lettura.
2. Crea un puntatore a FILE, apre/crea un file di nome esempio.txt inmodalità scrittura.
3. Apre/crea un file di nome esempio.txt in modalità scrittura e crea unpuntatore a FILE.
4. Crea un puntatore a FILE, apre/crea un file di nome «C:\\......esempio.txt»in modalità scrittura.
Quizzz
Il Mantra del file
1. Dichiarare puntatore a FILE → FILE *fp;
2. Aprire il file con fopen→ fp=fopen(nome, modo)
L’uscita di fopen() è una costante di valore NULL se il file aperto inlettura/append non esiste oppure c’è un errore nel nome del file.
È buon uso controllare che l’apertura sia andata a buon fine
if(fp==NULL) return 0;
o direttamente
if((fp=fopen(nome, modo))==NULL) return 0;
Apertura
Finora abbiamo visto come aprire un file e verificare che il processo sia andato bene a seconda della modalità che utilizziamo.
Ma una volta che il file è aperto, cosa si può fare??????
Scrivere ("w,a") Leggere ("r")(Che vediamo tra poco)
Possiamo considerare questo come il passo 4.
1. Dichiarare puntatore a FILE → FILE *fp;
2. Aprire il file con fopen → fp=fopen(nome, modo)
3. Controllo su fp → if(fp==NULL) return 0;
4. Scrittura/Lettura del file;
È tutto?
Gestione dei file
Chiusura di un file
int fclose(FILE *fp);
È la funzione che chiude il file dopo che su esso sono state compiute le operazionidesiderate, restituendo un valore diverso da 0 se l’operazione è andata a buon fine.
Un file va sempre chiuso al termine del suo utilizzo
Aggiungiamo quest’ultimo passo al mantra:
1. Dichiarare puntatore a FILE → FILE *fp;
2. Aprire il file con fopen → fp=fopen(nome, modo)
3. Controllo su fp → if(fp==NULL) return 0;
4. Scrittura/Lettura del file;5. Chiusura del file → fclose(fp);
Chiusura di un file
In pratica…
1
In pratica…
In pratica…
2
In pratica…
In pratica…
3
In pratica…
In pratica…
4
5
In pratica…
In pratica…
5
In pratica…
Scrittura di un file
fprintf(fp,stringaFormato,listaEspressioni);
Le funzioni di output su file hanno lo stesso comportamento di quelle di output su video, salvo l’indicazione del file pointer.
QuickQuizzzzzz
Avete una variabile di tipo float di nome ff, e volete scrivere su file puntato da fp la frase: "Ciao sono una variabile float e valgo %f !".Quale di queste forme è corretta?
Scrittura di un file
Lettura di un file
I caratteri vengono automaticamente prelevati dal file man mano che sono richiestidalle funzioni di input (e l’offset avanza) .
Le funzioni di input da file hanno lo stesso comportamento di quelle di input datastiera, salvo l’indicazione del file pointer
fscanf(fp,”%d”,&a);
QuickQuizzzzzz
Avete aperto un file in lettura, quale di questi comandi vi permette di leggere un valore intero dal file appena aperto?
Lettura di un file
Ciclo di lettura da file
Approfondiamo la questione di come solitamente si legge da un file.
Esistono diverse soluzioni che hanno come obiettivo finale quello di capire quando si arriva allafine del file.
Se ricordate, per le stringhe esiste un carattere speciale ‘/0’ che vi segnala la fine della stringa.
Allo stesso modo esiste un carattere speciale che segnala la fine di un file. Tale carattere sichiama EOF (End Of File).
Per determinare se si è raggiunta la fine del file (ossia non c’ è più niente da leggere):
1. Si controlla il valore restituito dalle funzioni di input dopo la lettura (restituiscono lasegnalazione di fine file quando la lettura di un record fallisce, NON appena letto l’ultimovalore).
2. Si usa la funzione feof prima di fare la lettura
Ciclo di lettura di un file
Esempio corretto di lettura da file (si usa tipicamente):
while (fscanf(fp,"%d", &x) != EOF){
istruzioni
}
La funzione fscanf legge un valore (uno solo) e viene valutato ilrisultato:• Se è EOF : la lettura è fallita e x non ha cambiato valore;• Se non è EOF : un valore è stato letto dal file e memorizzato in x,
l’offset viene fatto avanzare del numero di byte pari ai caratteri letti(se legge 12 avanza di 2 caratteri);
Ciclo di lettura di un file: Metodo 1
Ciclo di lettura da file: Soluz. 2
int feof(FILE *fp);
• Questa funzione restituisce 0 se la condizione di fine file non è stata raggiunta, un valorediverso da 0 in caso contrario
• Fornisce risultati corretti solo dopo aver tentato di leggere oltre la fine del file, quindi non sipuò usare per stabilire se un file è vuoto oppure no prima di iniziare a leggerlo e in generepresenta diversi problemi.
Vi consiglio perciò quando è possibile di adottare la soluzione 1
Ciclo di lettura di un file: Metodo 2
Tip&Tricks
• Se indicate il percorso, è necessario separare le parti per mezzo di un carattere backslash \(Windows) e che per inserire questo nelle stringhe costanti è necessario raddoppiarlo (ilprimo fa da escape): "C:\\Documenti\\file.txt«
• Si ricordi che quando il backslash viene introdotto dall’utente, non lo si deve inveceraddoppiare
Si possono leggere coppie/terne/ecc di valori semplicemente aggiungendo le rispettive stringhe di controllo.
fscanf(fp,”%d %d”,&a,&b);
Es. Si aspetta di legge due valori interi da file e li memorizza nelle variabili a e b
Tip&Tricks
Esercizio 2 - 3
1. Scrivere con un editor un file contenente dei numeri, uno per riga.Sviluppare un programma che chieda all’utente il nome di questofile, lo apra e calcoli e stampi a video quanti sono i valori letti, ilvalore massimo, il valore minimo, la somma e la media di tutti ivalori presenti nel file.
2. Scrivere un programma che legga un file contenente coppie dinumeri interi (x e y), una per riga e scriva un secondo file checontenga le differenze x – y, una per riga. Si supponga che il file diinput non abbia errori e che nomi dei file vengano chiesti all’utente.
Consiglio: Quando si apre un file in lettura è sempre meglio controllare che non sia vuoto, intal caso il programma deve terminare.
Esercizio 1-2
Esercizio 4
Modellare l’esercizio 2 con le funzioni. Nello specifico create 3 funzioni:
• leggidati, che prende in ingresso il nome/percorso di un file e un array di strutture point (vedi sotto),e memorizza il contenuto del file in questo array di strutture. Restituisce il numero di valori letti (ladimensione di point).
• calcola, che prende in ingresso la struttura dati di point riempita e la sua dimensione, e calcola ladifferenza di x e y mettendola in un vettore passato in ingresso.
• scrividati, che prende in ingresso il nome/percorso del file da scrivere, il vettore risultante da calcolae la sua dimensione, e lo scrive nel file.
typedef struct{
int x,y;
}point;
NB: Dovete scrivere il main affinchè tutto funzioni!Concettualmente:
• Inizializzate tutte le variabili che vi servono (vettori e vettori di strutture)• Dovete acquisire i nomi dei file da passare alle funzioni
Esercizio 3
* Vedi ultima slide
*POINT_MAX mi serve perché devo passare il vettore PRIMA di leggere,quindi non posso sapere la dimensione finché non finisco la lettura.