Copy Link
Add to Bookmark
Report

C++ Lezione 10: I/O nei File (parte 1)

papero's profile picture
Published in 
LezioniC
 · 14 Aug 2021

Questo è un argomento un po' più avanzato di quelli trattati finora, ma penso che sia utile e che tornerà utile a molte persone. L'I/O nei files significa fondamentalmente leggere e scrivere files. Questa lezione tratterà solo i files di testo, cioè files che sono leggibili con un text editor, al contrario dei files binari (gli exe, per esempio). Non li tratterò molto, per esempio questa lezione non si occuperà della ricerca nei files o della lettura di dati specifici nei files. Sarà semplicemente incentrato sull'apertura, sulla scrittura e sulla lettura di files di testo. Non preoccupatevi, comunque, perché la lezione 11 tratterà meglio questo argomento.

Bene, come si fa a cominciare? I files hanno le loro funzioni specifiche da utilizzare, così come hanno il proprio tipo di dato, chiamato FILE (Ci sarebbe altro da dire su questo, ma adesso non è importante e verrà spiegato dopo, quando servirà). Il modo di usare il tipo FILE è lo stesso che si usa con gli integer, o con i float, o con i char:

 FILE *newfile; //Crea un FILE chiamato newfile (non dimenticate che è 
//un puntatore)

Ora, non lo possiamo usare a meno che non ci sia un modo di dare a FILE(*newfile) un file a cui puntare. Questo modo esiste e si chiama stream. Questo significa che questo è il posto dove andrà l'output. Per dirigere *newfile verso un file, il comando da usare è FILE *fopen(const char *filename, const char *mode), che si trova in stdio.h. Esso restituisce semplicemente un puntatore ad un FILE, ma è abbastanza semplice da usare. per esempio:

 FILE *newfile:                        	//Crea un FILE chiamato newfile 
newfile=fopen("c:\AUTOEXEC.BAT", "r"); //apre per la lettura il vostro file
//autoexec.bat e lo assegna
//a newfile

Sostanzialmente, fopen accetta due stringhe. Una è il nome del file, incluso il path e l'altra indica lo scopo per cui sarà utilizzato il file (il modo). In questo caso, la r denota che il file sarà aperto solo per la lettura. Perciò, il file non può essere modificato fintanto che è aperto. Questa è probabilmente una buona idea, perché editare il vostro file autoexec.bat con garbugli non è una buona idea!

Come riferimento, ecco un elenco dei modi differenti con cui aprire un file:

  • r Apre in sola lettura.
  • w Crea un file per scrittura. Se già esiste un file con questo nome, sarà sovrascritto.
  • a Append; apre in scrittura alla fine del file, o crea il file se non esiste.
  • r+ Apre un file esistente in lettura e scrittura.
  • w+ Crea un nuovo file in lettura e scrittura. Se un file con questo nome esiste già, sarà sovrascritto.
  • a+ Apre per l'append; apre (o crea se il file non esiste) per aggiornare alla fine del file.

Tenete presente che ognuno di questi ha un uso differente, e che dovete scegliere il più appropriato per il vostro lavoro. Per ora, comunque, concentriamoci sulla lettura di files.

Ora, diciamo che volete stampare a schermo il contenuto del file autoexec.bat. Supponendo che vogliate fare un programma che faccia ciò, vi serve una funzione per leggere da un file. Ce ne sono molte e utili, ma per ora useremo int fgetc(FILE *stream)(Notare che restituisce un int, ma il range sarà ancora stampabile (è lo stesso dei char), definito in iostream.h). Fondamentalmente, fgetc otterrà il carattere successivo da un file che gli viene passato(cioè, lo stream che gli avete dato). Un esempio potrebbe essere il seguente codice per mostrare qualche carattere iniziale del vostro file autoexec.bat:

 #include <iostream.h> //Per cout 
#include <stdio.h> //per tutti le funzioni di i/o per i files
void main()
{
int count=0; //Solo una variabile per evitare la lettura perpetua del file.
FILE *afile; //Ci serve un FILE per puntare allo stream per
//l'accesso al file
afile=fopen("c:/AUTOEXEC.BAT", "r"); //Apre il fileautoexec.bat
//per leggerlo
//No, non so perché ci serve uno slash a rovescio.
while(count<10)
{
cout<<(char)fgetc(afile); //Da notare che fgetc restituisce un int,
//che può essere stampato.

//Notate l'uso di (char) per effettuare il 'typecast' all'integer
//restituito. Questo significa che lo rende un carattere stampabile
//dal numero. Ci sono altre informazioni su questo argomento nella
//lezione 11, che vi suggerisco di leggere.
//(Notare che i chars fondamentalmente convertono i loro numeri ASCII
//nel carattere stampabile appropriato. Per esempio 65='A' .
count++; //Non penso che debba venire letto all'infinito, giusto?
}
fclose(afile); //Sorpresa (niente paura, usatelo semplicemente per
//chiudere un file quando avete finito di usarlo).
//Semplicemente ponete il puntatore nello stream
//(il FILE)
}

Questo programma è abbastanza semplice, e non utilizza molte operazioni su files del C molto utili. Notate, comunque, che stampa solo pochi caratteri. E se volessimo stampare tutto il file? Bene, è qui che entra in gioco una cosa chiamata EOF(end-of-file). Si tratta fondamentalmente di un null che segnalala che è stata raggiunta la fine del file.

Quindi, come si potrebbe fare un programma che lo usa? Bene, fgetc recupera un carattere dal file, e restituirà EOF quando raggiunge la fine del file. Ora, è possibile usare un loop che controlla se l'ultimo carattere è uguale a EOF. Per esempio, CHARACTERREAD!=EOF. Questo restituirà true se CHARACTERREAD non è EOF.

Questo è quello che ho fatto io:

 #include <iostream.h> //Per cout 
#include <stdio.h> //per tutte le funzioni i/o dei files
void main()
{
FILE *afile; //Dobbiamo definire un tipo FILE per aprire un file
afile=fopen("c:/AUTOEXEC.BAT", "r"); //Apre autoexec.bat, solo in lettura,
//non lo scrive. afile è ora lo stream
//che punta al file autoexec.bat,
//ed è usato per fare operazioni con
//autoexec.bat
char c; //Senza un carattere per memorizzare le informazioni il programma
//non funzionerà
while(c!=EOF) //Controlla per vedere se il carattere appena letto è la fine
//del file
{
c=fgetc(afile); //Questo legge il carattere
//Notare che non è necessario effettuare il typecast del risultato di fgetc
//dato che viene automaticamente convertito in un carattere stampabile
//quando char c è un carattere.
cout<<c; //Stampa il carattere (come dovreste SAPERE!)
}
fclose(afile); //Per prudenza, chiudiamo il file!
}

Ok, alla fine siete riusciti a stampare! Bene, qual è la cosa successiva da fare? Perché non avere un programma che fa un backup del file autoexec.bat? Qui c'è una nuova funzione che vi servirà di aggiungere al vostro repertorio prima che questo programma possa essere fatto. La nuova funzione è fputc, definita in stdio.h.

 int futc(int c, FILE *filethinghere); 

Essenzialmente, restituisce il carattere che gli viene dato, oppure restituisce un EOF. Accetta un carattere come primo argomento, e un puntatore a uno stream (il FILE) come secondo argomento. Qui c'è un esempio su come usarlo:

 fputc('A', newfile); //Scrive il carattere 'A' nel file puntato da newfile 

Comunque, non dimenticate che questo non funziona sempre. Il file che lo stream punta deve essere aperto in scrittura, non solo in lettura. Di solito dovrete fare un append a un file, ma nel caso del nostro prossimo esempio vogliamo creare un nuovo file, e sovrascriverne uno vecchio.

Ora che abbiamo una funzione per scrivere in un file, perché non terminare il programma per il backup dell'autoexec.bat? Essenzialmente, useremo lo stesso loop della prima funzione, cioé controllando per vedere se è stata raggiunta la fine del file, altrimenti continuerà a stampare caratteri. Questa volta, comunque, i caratteri non verranno stampati sullo schermo. Invece, verranno stampati in un altro file (nell'esempio, backup.aut).

--------------
ATTENZIONE: Se avete un file che già si chiama backup.aut verrà sovrascritto!
NON lanciate il programma di esempio se avete il file backup.aut nella directory del vostro compilatore! Altrimenti verrà sovrascritto.
--------------

 #include <stdio.h> //Necessario perle funzioni i/o dei files (inclusa fopen!) 

void main()
{
FILE *autoexec, *backup; //Questa volta ci sono due files, AUTOEXEC.BAT
//e il file di backup
autoexec=fopen("c:\AUTOEXEC.BAT", "r");//Apre autoexec.bat in lettura
backup=fopen("backup.aut", "w"); //Crea (o sovrascrive)backup.aut in
//scrittura
char c; //Ci serve un buffer per leggere i caratteri
while(c!=EOF) //Controlla solo il raggiungimento della fine del file
{
c=fgetc(autoexec); //Legge un carattere da autoexec.bat
fputc(c, backup); //Scrive un carattere nel file di backup!
}
fclose(autoexec);
fclose(backup); //Chiude i files per terminare!
}

Wow! E' un programma che può essere utile. Siete liberi di usarlo quando volete. Ricordatevi solo come funziona. Non pensate che questa è la fine delle informazioni sull i/o dei files. C'è dell'altro, ma per ora dovrebbe essere sufficiente per stimolare il vostro appetito. Oh, e potete usare fputc anche per scrivere l'input dell'utente in un file! penso che ve l'eravate immaginato!


---
Nota: La mia homepage è http://www.cprogramming.com. La mia email è webmaster@cprogramming.com. Vi prego di mandarmi una email con commenti e/o suggerimenti. Se volete usare questo tutorial nel vostro sito, vi prego di mandarmi una email e dia aggiungere un link a http://www.cprogramming.com.
Grazie :)

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT