Manipulação de arquivos em C++

Manipulação de arquivos em C++

Manipulação de arquivos significa ler e gravar arquivos (como .txt, .csv etc.) usando classes fornecidas pela biblioteca padrão C++.

  • Os programas são executados na RAM, o que significa que os dados existem apenas enquanto o programa está em execução. Quando um programa termina, todos os dados na RAM são perdidos automaticamente.
  • O manuseio de arquivos permite armazenar dados na memória secundária (como HDD ou SSD) para que possam ser preservados permanentemente e salvos e acessados ​​mesmo após o término do programa.
  • Para operações de arquivo, C++ fornece classes de fluxo de arquivo no cabeçalho como ofstream ifstream fstream.

Abrindo um arquivo

Antes de ler ou escrever em um arquivo, primeiro precisamos abri-lo. Abrir um arquivo carrega esse arquivo na RAM. Em C++, abrimos um arquivo criando um fluxo para ele usando o stream classe que representa o fluxo do arquivo, ou seja, fluxo de entrada e saída para o arquivo.

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

onde

  • str: Nome dado ao stream
  • nome do arquivo: Nome do arquivo
  • modo : Representa a forma como vamos interagir com o arquivo.

Modos de abertura de arquivo

O modo de abertura de arquivo indica que o arquivo está aberto para leitura, gravação ou acréscimo. Abaixo está a lista de todos os modos de arquivo em C++:

Modo Descrição
ios::em Arquivo aberto para leitura. Se o arquivo não existir, a operação de abertura falhará.
ios::fora Arquivo aberto para gravação: o buffer de fluxo interno suporta operações de saída.
ios::binário As operações são executadas em modo binário em vez de texto.
ios::comeu A posição de saída começa no final do arquivo.
ios::aplicativo Todas as operações de saída acontecem no final do arquivo, anexando ao seu conteúdo existente.
ios::tronco Qualquer conteúdo que existia no arquivo antes de ele ser aberto será descartado.

Por exemplo se quisermos abrir o arquivo para leitura usamos o seguinte modo de abertura:

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

Da mesma forma, se quisermos abrir o arquivo para escrita, usamos o seguinte:

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

Esses modos também podem ser combinados usando o operador OR (|). Por exemplo, você pode abrir o fluxo de arquivos nos modos de leitura e gravação, conforme mostrado:

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

Se o arquivo aberto em modo de gravação não existir, um novo arquivo será criado. Mas se o arquivo aberto em modo de leitura não existir, nenhum novo arquivo será criado e uma exceção será lançada

Outros fluxos de arquivos

stream não é o único fluxo de arquivos fornecido pelo C++. Existem mais dois fluxos especializados:

  • ifstream : significa fluxo de arquivo de entrada. É equivalente a abrir fstream em ios::em modo.
  • ofstream : significa fluxo de arquivo de saída. É equivalente a abrir o fstream em ios::fora modo.

Os modos acima são modos padrão para esses fluxos. Esses modos não podem ser alterados, mas podem ser combinados com outros modos. Agora, para entrada, também podemos usar ifstream conforme mostrado:

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

Da mesma forma para saída:

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

Gravar dados em arquivo

Depois que o arquivo for aberto no modo de gravação usando stream ou ofstream podemos realizar a operação de gravação de maneira semelhante ao cout usando < < 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  ;   }   
escreverGFG.texto

Ler dados do arquivo

Uma vez que o arquivo é aberto no modo de leitura usando fstream ou ifstream, podemos realizar a operação de gravação de maneira semelhante a cin usando >> operador.

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  ;   }   


Saída

 Read String: Welcome  

Isso tem o mesmo problema que cin. A entrada só é feita até o primeiro caractere de espaço em branco. Para evitar isso podemos usar o getline() funcionar como mostrado:

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  ;   }   


Saída

 Read String: Welcome to GeeksforGeeks.  

Fechando o arquivo

Fechar o arquivo significa fechar o fluxo associado e liberar os recursos que estamos utilizando. É importante fechar o arquivo depois de terminar, especialmente em programas de longa execução, para evitar vazamentos de memória, perda de dados, etc.

Em C++ os arquivos são fechados usando o fechar() função de membro que está presente em todos os fluxos de arquivos.

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  ;   }   


Saída

 Read String: Welcome to GeeksforGeeks.  

Erros no manuseio de arquivos

Muitos tipos diferentes de erros podem ocorrer no manuseio de arquivos, como arquivo não encontrado, disco cheio, etc. Nossos programas devem esperar erros comuns e devem ser capazes de tratá-los adequadamente. A seguir estão alguns erros comuns que podem ocorrer durante o manuseio de arquivos:

Falha ao abrir arquivo

Pode haver casos em que o arquivo não é aberto por vários motivos, como ele não existe ou o programa não tem permissão para abri-lo, etc. is_open() função de membro das classes de fluxo de arquivo para verificar se o arquivo foi aberto com sucesso ou não.

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  ;   }   


Saída

 Error: Unable to open file!  

Falha ao ler/gravar dados

Outro erro comum é a falha na leitura ou gravação de dados por motivos como modo incorreto, etc. Nesse caso, podemos validar as operações após cada tentativa de leitura/gravação. Por exemplo, a leitura usando getline() pode ser validada como 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  ;   }   


Saída

 Error: Failed to read data  

Erro de fim de arquivo (EOF)

Tentar ler além do final do arquivo pode causar um erro EOF. Isso pode acontecer quando você não verifica o final do arquivo antes de lê-lo. Podemos verificar EOF usando eof() função de 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  ;   }   


Saída

 Reached end of file.  

Observe que também validamos a operação de leitura antes de verificar o EOF como getline() só retornará nullptr mesmo que a leitura falhe por qualquer motivo.

Tratamento de arquivos binários

Em C++ também podemos lidar com arquivos binários que armazenam dados em formato bruto. Para ler e escrever dados binários deve-se usar o ios::binário flag ao criar/abrir um arquivo binário.

Escreva em arquivo binário

Para gravar dados em um arquivo binário, primeiro precisamos abrir ou criar o arquivo em ios::binário modo.

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  ;   }   


Saída

escreverBinárioArquivo Binário

Lendo de arquivo binário

Assim como abrimos um arquivo em modo binário para gravar dados para ler dados de um arquivo binário, devemos abrir o arquivo em modo de leitura usando ios::em .

Sintaxe:

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  ;   }   


Saída

 File Data: Welcome to GeeksForGeeks  

Outras operações de arquivo

Também podemos realizar mais operações para manipular um arquivo de nosso programa C++. algumas das operações de arquivo comuns são:

  • Programa C++ para excluir um arquivo
  • Anexar uma string em um arquivo existente
  • Copie um arquivo para outro arquivo
Criar questionário