Il file è un un contenitore di testo che si può conservare sulla memoria di massa permanente (sul disco fisso, sul ssd, su una usb key). E’ in effetti una “unità logica di memorizzazione” nel senso che si può considerare come una grandezza elementare in cui salvare i dati. La memoria di massa è piena di questi file.

Il linguaggio C può gestire i file attraverso le funzioni contenute nella libreria <stdio.h>, normalmente usata per scrivere i nostri programmi. Le dimensioni di un file non sono predefinite: un programma in C vede il file come una sequenza di elementi (caratteri o parole), che si chiamano “record logici”,  che termina con un marker, cioè con un carattere speciale detto EOF (end of file). Il linguaggio C distingue due tipi di file: file di testo e file binari, visti come sequenze di bit.

File di testo. I file di testo sono sequenze di caratteri organizzati in linee. Ogni linea termina con un carattere speciale detto “newline” cioè “\n”. Possiamo considerare che sia i singoli caratteri, sia le parole, sia le intere linee possono essere intese come singoli record logici di cui un file è fatto.

I record logici che compongono il file sono in esso organizzati in modo sequenziale e ordinato, pertanto, per accedere ad un particolare record logico, è necessario scorrere tutti i precedenti fino ad arrivare ad esso. Un programma scritto in C ed il file “esempio.txt” su cui esso opera sono cose diverse, pertanto, nel programma si usa una variabile che fa riferimento al file ed al record logico presente nel file. Questa variabile è un “puntatore al file” e si “dichiara” in questo modo:

FILE *punta;

Creando una variabile “puntatore al file” posso eseguire su esso una serie di operazioni (apri il file, leggi, scrivi, chiudi il file). Per lavorare su un file si procede facendo 3 cose:

  1. apertura del file: prima di operare sul file dobbiamo “accedervi”, “aprirlo” ed indicare cosa vogliamo fare con esso (scriverci o leggerlo o entrambe le cose);
  2. accesso ed operazioni sul file;
  3. chiusura del file: alla fine delle operazioni, il file va “chiuso” in modo da rendere “permanenti” le modifiche.

Apertura del file.

Si effettua con l’istruzione “fopen()” che ha questa sintassi:

FILE* fopen (char *nome,  char *modo)

  • nome è un vettore di caratteri (esempio “pippo.txt” oppure “documento.txt”) che indica il nome del file presente in memoria di massa;
  • modo è un altro vettore di caratteri che indica cosa si vuol fare col file:
    • “r” usate questa espressione per operare in lettura;
    • “w” usate questa espressione per operare in scrittura a partire dall’inizio del file;
    • “a” usate questa espressione per operare in scrittura a partire dalla fine del file;
    • “rb” “wb” ab”  usate queste espressioni per operare su file binari;

La funzione “fopen()” restituisce un puntatore a file aperto (ovviamente al file indicato tra le parentesi tonde). Se il file non esiste, oppure è in sola lettura quando si voleva scrivere etc, l’istruzione “fopen()” restituisce il valore speciale NULL.

Esempio:

FILE* punta;

punta = fopen(“esempio.txt”, “r”);

Se il file è presente e non è vuoto, fopen restituisce a punta il puntatore al primo record logico nel file (vedi figura).

 

Se si effettua l’apertura del file in scrittura:

punta = fopen(“esempio.txt”, “w”);

il contenuto del file viene perso e la scrittura avviene a partire dal primo record logico. Il marker EOF viene spostato a inizio file dopo il/i record locico/i scritto/i.

Se invece voglio scrivere in coda agli altri record logici (parole) già presenti, devo usare la scrittura in “append” cioè in aggiunta:

punta = fopen(“esempio.txt”, “a”);

in questo modo il puntatore scorre tutto il file e si posiziona alla fine, in corrispondenza del precedente EOF (che viene spostato) ed il contenuto precedente non viene perso.

N.B. nel riferimento al nome del file posso usare anche il path (percorso) del file:

punta = fopen(“c:\anna\dati\esempio.txt”, “w”);

Chiusura di un file.

Dopo aver operato su un file, lo stesso va “chiuso” per confermare le operazioni fatte. L’istruzione da usare è “fopen()”:

int  fclose(punta);

Fclose() deve operare su “punta” cioè sul nome del puntatore al file che si sta chiudendo. Fcolse() restituisce un intero che vale :

  • “0” (Zero) se l’operazione è andata a buon fine
  • “EOF” in presenza di qualche errore.

Esempio:

  • #include <stdio.h>
  • main (){
  •     FILE* punta;
  •     punta = fopen(“prova.txt”, “w”);
  •     …..
  •     fclose(punta);
  •     ……

Osservazioni: printf() e scanf() sono indirizzati sulle periferiche Monitor e Tastiera dette “standard output” e “standard input” perchè sono le periferiche fondamentali per fare operazioni di input ed output. Per fare input (scrittura) ed output (lettura) sul file si usano comandi simili.

  1. fscan, fpintf : lettura e scrittura “con formato”;
  2. fgetc, fputc  :  lettura e scrittura  di caratteri;
  3. fgets, fputs :  lettura e scrittura  di stringhe;
  4. fread,  fwrire : lettura e scrittura di blocchi di bit.

Fscan ed Fprint: lettura e scrittura “con formato”.

Sono funzioni simili a scanf e prinf, solo che si aggiunge un parametro: il puntatore al file su cui si opera.

 

Lettura da un file. Esempio:  fscanf (punta, “%d%f“, &km, &h). formalmente la funzione fscanf è la seguente: int fscanf (FILE *fp,  stringa, elementi)

dove:

  1. fp : è il puntatore al file
  2. stringa : indica il FORMATO dei dati da leggere
  3. elem : lista dei valori da leggere

Confornto :    scanf(“%d”, &dato)    —–>>  fscanf(fp, “%d”, &dato).

 

Scrittura di un file. Esempio: fprintnf (punta, “ciao come va? Oggi corriamo per %d chilometri“, km). formalmente la funzione fprintf è la seguente: int fprintf (FILE *fp,  stringa, elementi)

dove:

  1. fp : è il puntatore al file
  2. stringa : è la stringa da scrivere
  3. elem : lista dei valori da scrivere

Confornto :    printf(“Hai speso %d dollari”,  dollari)    —–>>  fprintf(fp, “Hai speso %d dollari”,  dollari)

Conclusioni: si può dire che scanf e printf siano dei casi particolari di fscanf e fprintf dove il puntatore al file è omesso perchè è lo standard out e lo standard in:

  • fprintf (stdout,  stringa,  elementi);
  • fscanf (stdin,  stringa,  elementi);

 

 

Riferimenti:

http://lia.disi.unibo.it/Courses/FondT-0910-ELT/materiale/10.file.pdf