Sei sulla pagina 1di 37

Corso di Fondamenti di Informatica

Ingegneria delle Comunicazioni – BCOR


Ingegneria Elettronica – BELR

Introduzione al C
Unità 9 – File

D. Bloisi, A. Pennisi, S. Peluso, S. Salza, C. Ciccotelli


Sommario
• Input/Output
• Stream
• File

Unità 9 - File 2014/2015 Pagina 2


I/O in C
Il sistema di I/O del C è una interfaccia uniforme
per il programmatore indipendentemente dal
dispositivo di lettura e scrittura utilizzato.

Scrivere o leggere da file o da video/tastiera non


comporta differenze.

Unità 9 - File 2014/2015 Pagina 3


Schema di un calcolatore

Tastiera Hard Disk


Controller
Mouse Porte I/O Dischi
CD-ROM
Stampante DVD
Modem
Scheda
CPU Monitor
Video

Scheda Altoparlanti
Memoria Microfono
Audio

Scheda Internet
Rete

Bus
Unità 9 - File 2014/2015 Pagina 4
Sistema di I/O
Il sistema di I/O del C crea un livello di astrazione
tra il programmatore e l’oggetto (sia esso un file
o dispositivo).

Viene creato un meccanismo di astrazione


tramite un flusso di dati o stream.

Unità 9 - File 2014/2015 Pagina 5


Stream
Uno stream (flusso di dati) fornisce un canale di
comunicazione tra il programma e l’esterno (file
o device).

Uno stream è una struttura costituita da una


sequenza di byte terminante con un apposito
byte che ne identifica la fine (EOF).

Unità 9 - File 2014/2015 Pagina 6


Stream
Gli stream possono essere associati a:

• Dispositivi fisici collegati al computer (tastiera,


video, stampante, ecc.)

• File residenti su memoria di massa

Unità 9 - File 2014/2015 Pagina 7


Stream
Gli stream sono di fatto flussi di byte (una
sequenza di byte).

La fine di uno stream è indicata dal valore


speciale EOF (End-Of-File).

EOF è una macro definita in stdio.h

Unità 9 - File 2014/2015 Pagina 8


Bufferizzazione
Poiché l’accesso ai dispositivi ha un certo costo
(in termini di tempo), quando si accede ad un
dispositivo in lettura conviene leggere un
"blocco" di byte, invece che un byte alla volta.

In questo modo se si vogliono leggere n byte


(consecutivi) occorreranno solo accessi
(dove B è la dimensione del "blocco"), invece di
n accessi.
Unità 9 - File 2014/2015 Pagina 9
Bufferizzazione
Per lo stesso motivo quando si accede ad un
dispositivo in scrittura, invece di effettuare un
accesso per ogni byte scritto, conviene
accumulare un intero "blocco" di byte, per poi
scrivere tutti i byte del blocco con un singolo
accesso.

Unità 9 - File 2014/2015 Pagina 10


Bufferizzazione
Questo meccanismo è automatico e avviene per
mezzo di alcune aree temporanee di memoria,
dette buffer, in cui vengono memorizzati i
"blocchi" di byte letti dai dispositivi o da scrivere
sui dispositivi.

Gli stream di I/O sono bufferizzati: le funzioni C


che vedremo leggono/scrivono i byte non
direttamente dai dispositivi, ma da questi buffer.
Unità 9 - File 2014/2015 Pagina 11
Bufferizzazione
Questo meccanismo rende efficiente l'I/O, ma è
necessario fare attenzione:
i dati scritti in un buffer non compaiono nel file
(o nel dispositivo) finché il buffer non è riempito
o scaricato.

Ad esempio quando l’output è verso lo schermo,


il buffer viene automaticamente scaricato
quando si immette il carattere '\n'.
Unità 9 - File 2014/2015 Pagina 12
FILE
Esiste una struttura di dati interna al C, FILE, che
rappresenta uno stream ed è definita nel file stdio.h.

Viene usato il nome FILE per motivi storici, anche se la


struttura FILE può essere usata per rappresentare un
oggetto diverso da un file in “senso tecnico”.

E' sufficiente fare riferimento alla struttura FILE nei


programmi C quando si realizza l'I/O utilizzando uno
stream.
Unità 9 - File 2014/2015 Pagina 13
FILE
La struttura FILE rappresenta un puntatore ai byte dello
stream.

In stdio.h sono definiti tre puntatori a FILE particolari:


• stdin: rappresenta lo standard input (normalmente la
tastiera)
• stdout: rappresenta lo standard output
(normalmente il video)
• stderr: rappresenta lo standard error (normalmente
il video)
Unità 9 - File 2014/2015 Pagina 14
Esempio

• La funzione printf scrive su stdout

• La funzione scanf legge da stdin

Unità 9 - File 2014/2015 Pagina 15


File
I file rappresentano la principale struttura per la
memorizzazione di dati in maniera permanente su
memoria di massa (hanno la caratteristica di
sopravvivere allo spegnimento della macchina).

Essi possono contenere caratteri alfanumerici codificati


in formato standard (es. ASCII) direttamente leggibili
dall’utente (file di testo), oppure dati in un formato
interpretabile dai programmi (file binari ).

Unità 9 - File 2014/2015 Pagina 16


File
In questo corso tratteremo solo file di testo.

Solitamente questo tipo di file sono organizzati


in linee, cioè sequenze di caratteri separate dal
carattere '\n'.

Unità 9 - File 2014/2015 Pagina 17


File e directory
Ogni file è caratterizzato da un nome e risiede in un
determinato percorso (file path) nell’albero delle
directory.

Le operazioni fondamentali sui file sono: creazione,


lettura, scrittura, rinominazione ed eliminazione.

Queste operazioni possono essere effettuate tramite il


sistema operativo (o altri programmi applicativi) oppure
mediante apposite istruzioni del linguaggio C.
Unità 9 - File 2014/2015 Pagina 18
Operazioni sui file
Per eseguire operazioni di lettura e scrittura sui
file è necessario:

• Aprire il file prima di eseguire le operazioni

• Chiudere il file dopo aver eseguito le


operazioni

Unità 9 - File 2014/2015 Pagina 19


Aprire un file
L’apertura di un file avviene per mezzo della funzione
fopen:

FILE *fopen(const char *path, const char *mode);

• path è una stringa che indica il percorso ed il nome


del file.
• mode è una stringa che indica la modalità di accesso.
• Il tipo di ritorno (FILE *) è un puntatore al file pointer
associato allo stream.
Unità 9 - File 2014/2015 Pagina 20
Percorso del file (file path)
Il percorso del file (path) può essere:
• Assoluto: cioè specificato a partire dalla directory
radice (es.: "C:\" in windows, "/" in *nix)

• Relativo: cioè relativo alla directory di lavoro (cioè la


directory in cui si lancia il programma)

In particolare se si specifica solo il nome del file, il suo


percorso è relativo alla directory di lavoro (quindi deve
risiedere in tale directory)
Unità 9 - File 2014/2015 Pagina 21
Modalità di accesso (1/2)
Le modalità di accesso sono:
• "r": apre il file in sola lettura. Lo stream è posizionato
all’inizio del file.
• "r+": apre il file in lettura e scrittura. Lo stream è
posizionato all’inizio del file.
• "w": apre il file in sola scrittura. Se il file non esiste lo
crea, se esiste cancella il contenuto. Lo stream è
posizionato all’inizio del file.
• "w+": come "w" ma apre il file sia in lettura che in
scrittura.

Unità 9 - File 2014/2015 Pagina 22


Modalità di accesso (2/2)

• "a": (append) come "w" ma il puntatore allo stream è


posizionato alla fine del file.

• "a+": (append) come "w+" ma il puntatore in lettura è


posizionato all’inizio del file, mentre il puntatore in
scrittura è posizionato alla fine del file.

Unità 9 - File 2014/2015 Pagina 23


Modalità di accesso
Esempi:

// accesso al file dati.txt in lettura


FILE *fp1 = fopen("dati.txt", "r");

// accesso al file test.txt in lettura e scrittura


FILE *fp2 = fopen("test.txt", "w+");

Unità 9 - File 2014/2015 Pagina 24


Chiusura dello stream
La chiusura di uno stream libera le risorse ad esso
associate e si effettua attraverso la funzione fclose:

int fclose(FILE *fp);

• fp: file pointer associato allo stream da chiudere.


• Restituisce 0 in caso di successo, EOF in caso di
errore.

Unità 9 - File 2014/2015 Pagina 25


La funzione fprintf
• Analoga alla printf, viene usata per scrivere su
uno stream generico:

int fprintf(FILE *stream, const char *format,


<argomenti>);

• stream: lo stream su cui scrivere


• format & <argomenti>: come per la printf.
• Restituisce il numero di caratteri scritti.

Unità 9 - File 2014/2015 Pagina 26


La funzione fscanf
• Analoga alla scanf, viene usata per leggere da
uno stream generico:

int fscanf(FILE *stream, const char *format,


<argomenti>);

• stream: lo stream da cui leggere.


• format & <argomenti>: come per la scanf.
• Restituisce il numero di elementi correttamente letti, o EOF se
la fine dello stream è stata raggiunta.

Unità 9 - File 2014/2015 Pagina 27


fprintf & fscanf
NOTA:

• printf(<format>, <args>) corrisponde a:


fprintf(stdout,<format>,<args>)

• scanf(<format>, <args>) corrisponde a:


fscanf(stdin,<format>,<args>)

Unità 9 - File 2014/2015 Pagina 28


Esempio
Scrivere i primi 10 numeri in un file data.txt

int main (void) {


int i;
FILE *fp = fopen("data.txt", "w");
for (i = 1; i <= 10; i++) {
fprintf(fp, "%d\n", i);
}
fclose(fp);
return 0;
}
Unità 9 - File 2014/2015 Pagina 29
Esempio
Leggere 10 numeri interi da un file data.txt e stamparli a video

int main (void) {


int i, x;
FILE *fp = fopen("data.txt", "r");
for (i = 1; i <= 10; i++) {
fscanf(fp, "%d", &x);
printf("%d\n", x);
}
fclose(fp);
return 0;
}

Unità 9 - File 2014/2015 Pagina 30


Eccezioni (1/2)
Nell’aprire un file può accadere che qualcosa
vada storto (es.: il file non esiste, errori di I/O,
ecc.)

In tal caso la fopen restituisce il puntatore nullo:


NULL.

Unità 9 - File 2014/2015 Pagina 31


Eccezioni (2/2)
Per questo motivo dopo la fopen occorre
sempre eseguire un controllo.
Es.:
FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
// gestione dell’errore
printf("Errore nell’aprire il file\n");
exit(1);
}

Unità 9 - File 2014/2015 Pagina 32


Modello ideale per il file
Un file può essere immaginato come un nastro con
delle informazioni ed una testina di lettura/scrittura
che è l’indicatore di posizione.

La testina viene spostata da funzioni come


fscanf e fprintf o in modo esplicito con fseek.

C i a o EOF

Unità 9 - File 2014/2015 Pagina 33


Funzione fseek
int fseek(FILE *stream, long offset,
int whence);

Imposta la nuova posizione dell’indicatore di posizione puntato


da stream. La nuova posizione (in bytes) è ottenuta sommando
offset alla posizione specificata da whence.
Se whence è SEEK_SET, SEEK_CUR, o SEEK_END l’offset è
relativo rispettivamente all’inizio del file, alla posizione corrente
dell’indicatore di posizione oppure alla fine del file.
Ritorna 0 in caso di successo, -1 altrimenti.

Unità 9 - File 2014/2015 Pagina 34


Leggere e scrivere caratteri
int fgetc(FILE *stream);
Analoga a getchar(), ma legge su uno stream
qualsiasi.

int fputc(int c, FILE *stream);


Analoga a putchar(c), ma scrive su uno stream
qualsiasi.

Unità 9 - File 2014/2015 Pagina 35


End-Of-File
La fine del file EOF viene codificata con un valore
speciale dipendente dalla macchina:

Tipicamente:
• Ctrl-z su Windows
• Ctrl-d su Unix/Linux/MacOs

Unità 9 - File 2014/2015 Pagina 36


Riassumendo
1. Dichiarazione del file pointer:
FILE *fp;
2. Apertura del file:
fp = fopen(<path>, <mode>);
3. Lettura/scrittura su file
(es.: fprintf, fscanf,fgetc,fputc)
4. Chiusura del file:
fclose(fp);

Unità 9 - File 2014/2015 Pagina 37