Gestione dei file in C++

Gestione dei file in C++

La gestione dei file significa leggere e scrivere su file (come .txt .csv ecc.) utilizzando le classi fornite dalla libreria standard C++.

  • I programmi vengono eseguiti nella RAM, il che significa che i dati esistono solo mentre il programma è in esecuzione quando un programma termina, tutti i dati nella RAM vengono persi automaticamente.
  • La gestione dei file consente di archiviare i dati nella memoria secondaria (come HDD o SSD) in modo che possano essere conservati in modo permanente e possano essere salvati e accessibili anche dopo la chiusura del programma.
  • Per le operazioni sui file C++ fornisce classi di flusso di file nel file intestazione come ofstream ifstream fstream.

Apertura di un file

Prima di leggere o scrivere su un file dobbiamo prima aprirlo. L'apertura di un file carica quel file nella RAM. In C++ apriamo un file creandone uno stream utilizzando il file fstream classe che rappresenta il flusso di file, ovvero il flusso di input e output nel file.

C++
   fstream     str  (  'filename.ext'       mode  );   

Dove

  • stringa: Nome assegnato allo stream
  • nome file: Nome del file
  • modalità : Rappresenta il modo in cui interagiremo con il file.

Modalità di apertura dei file

La modalità di apertura del file indica che il file è aperto per la lettura, la scrittura o l'aggiunta. Di seguito è riportato l'elenco di tutte le modalità file in C++:

Modalità Descrizione
ios::in File aperto per la lettura. Se il file non esiste, l'operazione di apertura fallisce.
ios::fuori File aperto in scrittura: il buffer del flusso interno supporta le operazioni di output.
ios::binario Le operazioni vengono eseguite in modalità binaria anziché in testo.
ios::mangiato La posizione di output inizia alla fine del file.
ios::app Tutte le operazioni di output avvengono alla fine del file aggiungendosi al suo contenuto esistente.
ios::tronco Qualsiasi contenuto esistente nel file prima che fosse aperto viene eliminato.

Per esempio se vogliamo aprire il file in lettura utilizziamo la seguente modalità di apertura:

C++
   fstream     filein  (  'file.txt'       ios  ::  in  );   

Allo stesso modo se vogliamo aprire il file in scrittura utilizziamo quanto segue:

C++
   fstream     fileout  (  'file.txt'       ios  ::  out  );   

Queste modalità possono anche essere combinate utilizzando l'operatore OR (|). Ad esempio puoi aprire il flusso di file sia in modalità lettura che scrittura come mostrato:

C++
   fstream     str  (  'file.txt'       ios  ::  in     |     ios  ::  out  );   

Se il file aperto in modalità scrittura non esiste viene creato un nuovo file. Ma se il file aperto in modalità lettura non esiste, non verrà creato alcun nuovo file e verrà generata un'eccezione

Altri flussi di file

fstream non è l'unico flusso di file fornito da C++. Esistono due flussi più specializzati:

  • ifstream : indica il flusso di file di input. Equivale ad aprire fstream in ios::in modalità.
  • ofstream : indica il flusso di file di output. Equivale ad aprire fstream in ios::fuori modalità.

Le modalità di cui sopra sono modalità predefinite per questi flussi. Queste modalità non possono essere modificate ma possono essere unite ad altre modalità. Ora per l'input possiamo anche usare ifstream come mostrato:

C++
   ifstream     filein  (  'file.txt'  );   

Allo stesso modo per l'output:

C++
   ofstream     fileout  (  'file.txt'  );   

Scrivi dati su file

Una volta aperto il file in modalità scrittura, utilizzare entrambi fstream O ofstream possiamo eseguire l'operazione di scrittura in modo simile a cout utilizzando < < operator.

C++
   #include          using     namespace     std  ;   int     main  ()     {      // Open a file      ofstream     file  (  'GFG.txt'  );          // Write the string to the file      file      < <     'Welcome to GeeksforGeeks.'  ;      return     0  ;   }   
scrivereGFG.testo

Leggi i dati dal file

Una volta aperto il file in modalità lettura utilizzando fstream o ifstream, possiamo eseguire l'operazione di scrittura in modo simile a cin utilizzando >> operatore.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      file     >>     s  ;      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


Produzione

 Read String: Welcome  

Questo ha lo stesso problema di cin. L'input viene preso solo fino al primo carattere di spazio bianco. Per evitare ciò possiamo usare il file getline() funzione come mostrato:

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


Produzione

 Read String: Welcome to GeeksforGeeks.  

Chiusura del file

Chiudere il file significa chiudere il flusso associato e liberare le risorse che stiamo utilizzando. È importante chiudere il file una volta terminato, soprattutto nei programmi a esecuzione prolungata per evitare perdite di memoria, perdita di dati, ecc.

In C++ i file vengono chiusi utilizzando l'estensione vicino() funzione membro presente in tutti i flussi di file.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      // Close the file      file  .  close  ();      return     0  ;   }   


Produzione

 Read String: Welcome to GeeksforGeeks.  

Errori nella gestione dei file

Possono verificarsi molti tipi diversi di errori nella gestione dei file, ad esempio file non trovato, disco pieno, ecc. I nostri programmi dovrebbero aspettarsi errori comuni e dovrebbero essere in grado di gestirli correttamente. Di seguito sono riportati alcuni errori comuni che possono verificarsi durante la gestione dei file:

Errore nell'apertura del file

Possono verificarsi casi in cui il file non viene aperto per vari motivi, ad esempio non esiste o il programma non dispone dell'autorizzazione per aprirlo, ecc. In questo caso possiamo utilizzare il comando è_aperto() funzione membro delle classi del flusso di file per verificare se il file è stato aperto correttamente o meno.

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'nonexistent_file.txt'       ios  ::  in  );      // Check if the file is opened      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      file  .  close  ();      return     0  ;   }   


Produzione

 Error: Unable to open file!  

Impossibile leggere/scrivere i dati

Un altro errore comune è la mancata lettura o scrittura dei dati per motivi quali modalità errata, ecc. In questo caso possiamo convalidare le operazioni dopo ogni tentativo di lettura/scrittura. Ad esempio, la lettura utilizzando getline() può essere convalidata come mostra:

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'GFG.txt'       ios  ::  out  );      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;          // Checking if getline() read successfully or not      if     (  !  getline  (  file       line  ))      cerr      < <     'Error: Failed to read data'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


Produzione

 Error: Failed to read data  

Errore di fine file (EOF).

Tentare di leggere oltre la fine del file può causare un errore EOF. Questo può accadere quando non controlli la fine del file prima di leggerlo. Possiamo verificare la presenza di EOF utilizzando eof() funzione membro.

C++
   #include          using     namespace     std  ;   int     main  ()   {      ifstream     file  (  'GFG.txt'  );      if     (  !  file  .  is_open  ())      {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;      while     (  getline  (  file       line  ))      cout      < <     line      < <     endl  ;      // Check for eof      if     (  file  .  eof  ())      cout      < <     'Reached end of file.'      < <     endl  ;      else      cerr      < <     'Error: File reading failed!'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


Produzione

 Reached end of file.  

Si noti che abbiamo anche convalidato l'operazione di lettura prima di controllare EOF as getline() ritorneremo soltanto nullptr anche se la lettura fallisce per qualsiasi motivo.

Gestione di file binari

In C++ possiamo anche gestire file binari che memorizzano i dati in formato grezzo. Per leggere e scrivere dati binari è necessario utilizzare il file ios::binario flag durante la creazione/apertura di un file binario.

Scrivi nel file binario

Per scrivere dati su un file binario dobbiamo prima aprire o creare il file in ios::binario modalità.

C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str     =     'Welcome to GeeksForGeeks'  ;      // Open a binary file for writing      ofstream     file  (  'fileBin.bin'       ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for writing.'  ;      return     1  ;      }      // Write the length of the string (size) to file first      size_t     strLength     =     str  .  length  ();      file  .  write  (  reinterpret_cast   <  const     char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Write the string to the binary file      file  .  write  (  str  .  c_str  ()     strLength  );      // Close the file      file  .  close  ();      return     0  ;   }   


Produzione

writeBinaryFile binario

Lettura da file binario

Proprio come apriamo un file in modalità binaria per scrivere dati per leggere dati da un file binario dobbiamo aprire il file in modalità lettura utilizzando ios::in .

Sintassi:

C++
   fstream     fileInstance  (  'fileName.bin'       ios  ::  in  |     ios  ::  binary  );   
C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str  ;      // Open the binary file for reading      fstream     file  (  'fileBin.bin'       ios  ::  in     |     ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for reading.'  ;      return     1  ;      }      // Read the length of the string (size) from the file      size_t     strLength  ;      file  .  read  (  reinterpret_cast   <  char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Allocate memory for the string and read the data      char     *  buffer     =     new     char  [  strLength     +     1  ];     // +1 for the null-terminator      file  .  read  (  buffer       strLength  );      // Null-terminate the string      buffer  [  strLength  ]     =     ''  ;      // Convert the buffer to a string      str     =     buffer  ;      // Print file data      cout      < <     'File Data: '      < <     str  ;      delete  []     buffer  ;      file  .  close  ();      return     0  ;   }   


Produzione

 File Data: Welcome to GeeksForGeeks  

Altre operazioni sui file

Possiamo anche eseguire più operazioni per manipolare un file dal nostro programma C++. alcune delle operazioni comuni sui file sono:

  • Programma C++ per eliminare un file
  • Aggiungi una stringa in un file esistente
  • Copia un file in un altro file
Crea quiz