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 ; }
GFG.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: WelcomeIsso 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++#includeusing 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ídaRead 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++#includeusing 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ídaRead 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++#includeusing 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ídaError: 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++#includeusing 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ídaError: Failed to read dataErro 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++#includeusing 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ídaReached 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ídaArquivo 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++C++fstream fileInstance ( 'fileName.bin' ios :: in | ios :: binary );#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ídaFile Data: Welcome to GeeksForGeeksOutras 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:
Criar questionário
- Programa C++ para excluir um arquivo
- Anexar uma string em um arquivo existente
- Copie um arquivo para outro arquivo
Arquivo Binário