Aprire un File in Linguaggio C
- La funzione
fopen
è utilizzata per aprire un file in C. - La modalità di apertura del file può essere specificata come secondo argomento della funzione
fopen
. - La funzione restituisce un puntatore a un oggetto
FILE
che rappresenta il file aperto, oppureNULL
se si è verificato un errore durante l'apertura del file. - È importante controllare il puntatore restituito da
fopen
per gestire eventuali errori di apertura del file. - La modalità di accesso specifica se il file deve essere aperto in lettura, scrittura o in modalità append. Inoltre, specifica se si tratta di un file di testo o di un file binario.
Apertura di un File
La funzione che la libreria standard del C mette a disposizione per aprire un file è la funzione fopen
, che sta per file open. La sua firma è la seguente:
Funzione fopen
#include <stdio.h>
FILE *fopen(const char * restrict filename,
const char * restrict mode);
La funzione fopen
richiede due parametri:
filename
: il nome del file da aprire (può includere il percorso).mode
: la modalità di apertura del file (ad esempio, lettura, scrittura, ecc.).
Restituisce un puntatore a un oggetto FILE
che rappresenta il file aperto, oppure NULL
se si è verificato un errore durante l'apertura del file.
Il primo argomento della funzione fopen
rappresenta una stringa che contiene il nome (il percorso o path più precisamente) del file da aprire. Il percorso contiene tutte le informazioni necessarie per localizzare il file nel file system, inclusi eventuali directory o sottodirectory. Esso può essere:
- assoluto: specifica il percorso completo dalla radice del file system (ad esempio,
/home/utente/documenti/file.txt
). - relativo: specifica un percorso relativo alla directory di lavoro corrente (ad esempio,
documenti/file.txt
), dove per directory di lavoro corrente si intende la directory in cui si trova il programma in esecuzione.
Il parametro filename
sotto Windows
Bisogna prestare particolare attenzione al parametro filename
sotto il sistema operativo Windows.
Sotto Windows, i percorsi dei file utilizzano la barra rovesciata (\
) come separatore di directory, mentre sotto Unix/Linux si utilizza la barra normale (/
).
Tuttavia, nelle stringhe in linguaggio C la barra rovesciata, o backslash viene adoperata per indicare i caratteri di escape. Quindi, ad esempio, in un filename del genere:
C:\percorso\file.txt
Le due barre rovesciate verrebbero interpretate come inizio dei caratteri di escape (inesistenti tra l'altro) \p
e \f
.
Pertanto, se si specifica un percorso assoluto o relativo in un programma C destinato a essere eseguito su Windows, è necessario utilizzare il carattere di escape \\
che rappresenta la singola barra rovesciata. Ad esempio:
FILE *file = fopen("C:\\percorso\\file.txt", "r");
Nelle ultime versioni di Windows e di Visual Studio, per ovviare a questo problema è possibile utilizzare la barra normale (/
) come separatore di directory, che viene interpretata correttamente anche nelle stringhe in linguaggio C. Ad esempio:
FILE *file = fopen("C:/percorso/file.txt", "r");
Il secondo argomento rappresenta una stringa che indica la modalità di accesso ossia si specifica quali operazioni si intendono effettuare sul file in questione. Un esempio è la modalità "r"
che indica che il file deve essere aperto in modalità lettura. Vedremo nella prossima sezione le modalità in dettaglio.
Notiamo due dettagli fondamentali riguardanti i parametri della funzione fopen
:
-
I parametri sono puntatori a
char
di tiporestrict
:Questo significa che le due stringhe,
filename
emode
, non devono sovrapporsi in memoria. -
Il parametro
mode
è un puntatore achar
, ossia una stringa e non rappresenta un singolo carattere. Infatti esso può essere composto da una sequenza di caratteri.
La funzione fopen
restituisce un puntatore a un oggetto FILE
che rappresenta il file aperto, oppure NULL
se si è verificato un errore durante l'apertura del file.
Tale puntatore deve essere salvato in una variabile per poi accedervi con altre funzioni nel resto del programma. Ad esempio:
FILE *file = fopen("esempio.txt", "r");
Le altre funzioni di accesso a file richiedono in ingresso il puntatore restituito da fopen
. Le vedremo nelle prossime lezioni.
Di solito, quando fopen
fallisce, ossia non riesce per vari motivi ad aprire il file, restituisce il valore NULL
.
Controllare sempre il puntatore restituito da fopen
Non bisogna mai assumere che la chiamata a fopen
abbia successo. Non è detto che un file possa essere aperto per una serie di motivi:
- Il file potrebbe non esistere;
- L'utente potrebbe non avere i permessi;
- Il file potrebbe essere stato aperto da un altro programma.
Quindi bisogna sempre controllare il puntatore restituito da fopen
prima di utilizzarlo. Ad esempio:
FILE *file = fopen("esempio.txt", "r");
if (file == NULL) {
perror("Errore nell'apertura del file");
return 1;
}
Modalità di Accesso ai File
Abbiamo detto che il secondo parametro della funzione fopen
permette di specificare la modalità di accesso al file.
Attraverso questo parametro, però, non si specifica solo la modalità di accesso ma anche il tipo di file, ossia se il file che si sta andando ad aprire sia un file di testo o un file binario. Quindi, le modalità di accesso si dividono in due gruppi a seconda del tipo di file.
Se il file a cui si vuole accedere è un file di testo, il parametro mode
può assumere uno dei seguenti valori:
Valore | Descrizione | Note |
---|---|---|
"r" |
Apertura in modalità lettura | Il file deve già esistere |
"w" |
Apertura in modalità scrittura partendo dall'inizio | Non è necessario che il file esista. Se non esiste esso viene creato. |
"a" |
Apertura in modalità scrittura (append) partendo dalla fine. | Se il file non esiste, viene creato. |
"r+" |
Apertura in modalità lettura e scrittura dall'inizio del file | Il file deve già esistere. |
"w+" |
Apertura in modalità lettura e scrittura partendo dall'inizio del file | Se il file non esiste, viene creato. Se esiste, viene troncato. |
"a+" |
Apertura in modalità lettura e scrittura partendo dalla fine del file | Se il file non esiste, viene creato. |
Viceversa, se il file è un file binario, il parametro mode
può assumere uno dei seguenti valori che sono simili ai precedenti ma in cui aggiungiamo una b
:
Valore | Descrizione | Note |
---|---|---|
"rb" |
Apertura in modalità lettura | Il file deve già esistere |
"wb" |
Apertura in modalità scrittura partendo dall'inizio | Non è necessario che il file esista. Se non esiste esso viene creato. |
"ab" |
Apertura in modalità scrittura (append) partendo dalla fine. | Se il file non esiste, viene creato. |
"r+b" o "rb+" |
Apertura in modalità lettura e scrittura dall'inizio del file | Il file deve già esistere. |
"w+b" o "wb+" |
Apertura in modalità lettura e scrittura partendo dall'inizio del file | Se il file non esiste, viene creato. Se esiste, viene troncato. |
"a+b" o "ab+" |
Apertura in modalità lettura e scrittura partendo dalla fine del file | Se il file non esiste, viene creato. |
Come si può osservare dalle due tabelle di sopra, la libreria standard del C distingue la scrittura su file in due modalità: writing (scrittura) e append (scrittura in coda o aggiunta).
Quando si apre un file in modalità scrittura, normalmente il file viene troncato (truncated), ossia se il file esisteva già, il suo contenuto viene eliminato e il file viene riempito con nuovi dati a partire dall'inizio.
Viceversa, se si apre un file in modalità append, i dati vengono scritti alla fine del file preservando il vecchio contenuto; questo ovviamente se il file esisteva già. Per questo si parla di append o aggiunta.
Le modalità ibride di lettura/scrittura, invece, richiedono particolare attenzione. Non si può leggere prima e poi scrivere (o viceversa) senza gestire correttamente la posizione nel file. La posizione nel file rappresenta l'offset corrente da cui si legge o si scrive. Ritorneremo su questo concetto nelle prossime lezioni in cui lo studieremo in dettaglio.