Manipulação de Arquivos
Transcrição
Manipulação de Arquivos Profª. Raquel Marcia Müller 1 Manipulação de Arquivos Para realizar E/S em arquivo, você precisa incluir o arquivo-cabeçalho fstream.h nos programas. Esse arquivo define muitas classes e valores importantes. Abrindo e fechando um arquivo Em C++ um arquivo é aberto pela ligação de um fluxo. Existem três tipos de fluxo: entrada, saída e entrada/saída. Para abrir um fluxo de entrada, você deve declará-lo para ser da class ifstream. Para abrir um fluxo de saída, ele deve ser declarado como class ofstream. Fluxos que realizarão tanto operações de entrada como de saída devem ser declarados como da class fstream. Exemplo: esse exemplo cria um fluxo de entrada, um de saída e um fluxo capaz de realizar tanto entrada como saída: ifstream in; ofstream out; fstream both; // entrada // saída // entrada e saída Uma vez criado um fluxo, uma maneira de associá-lo a um arquivo é utilizando-se a função open(). Essa função é um membro de cada uma das três classes stream. Seu protótipo é mostrado a seguir. Protótipo da função open( ): void open( char *nome do arquivo, int modo, int acesso; Aqui, nome do arquivo é o nome do arquivo que pode incluir um especificador de caminho. O valor de modo determina como o arquivo é aberto. Esse valor deve ser um (ou mais) destes (definidos em fstream.h): ios::app ios::ate ios::in ios::nocreate ios::noreplace ios::out ios::trunc Toda saída para um dado arquivo é acrescentada ao que já existe no arquivo. Só para arquivos que permitem escrita. Ocorre uma busca pelo final do arquivo quando o arquivo é aberto. Especifica que o arquivo é capaz de realizar entrada (leitura). Faz com que a função open() falhe se o arquivo não existir. Faz com que a função open() falhe se o arquivo já existir. Especifica que o arquivo é capaz de realizar saída (escrita). Faz o conteúdo de um arquivo já existente com o mesmo nome ser destruído e o arquivo ser truncado com tamanho zero. O valor de acess determina como o arquivo pode ser acessado. Esse valor corresponde aos códigos de atributos de arquivo do DOS mostrados aqui: Atributo 0 1 2 4 8 Significado Arquivo normal - acesso aberto Arquivo somente para leitura Arquivo oculto (escondido) Arquivo de sistema Bit de arquivamento fixado Criar um fluxo usando o modo ifstream significa criar um arquivo de entrada e criar um fluxo usando-se ofstream implica criar um arquivo de saída. Por este motivo, ainda que seja inteiramente apropriado abrir um arquivo usando a função open(), na maioria das vezes, você não irá usá-la, já que as classes ifstream, ofstream e fstream têm funções construtoras que abrem um arquivo automaticamente. Manipulação de Arquivos Profª. Raquel Marcia Müller 2 Exemplo: abrindo um arquivo de entrada sem a função open(): ifstream minhastream ("myfile"); // abre arquivo para entrada if( !minhastream ) { // erro no processo cout << "O arquivo não pode ser aberto!"; } Para fechar um arquivo, use a função membro close( ). Exemplo: usando a função close() para fechar o arquivo ligado a um fluxo chamado minhastream: minhastream.close; Lendo e escrevendo arquivos-texto Ler ou escrever de um arquivo-texto é simples, já que se pode simplesmente usar os operadores >> e <<. Exemplo: programa que escreve um inteiro, um valor em ponto flutuante e uma string para um arquivo chamado Teste.txt: #include <iostream.h> #include <fstream.h> void main (void) { // abre um arquivo para escrita de nome Teste.txt ofstream out( "Teste.txt" ); if( !out ) { cout << "O arquivo não pode ser aberto!"; return 1; } out << 10 << " " << 123.23 << endl; out << "Este é um pequeno arquivo-texto"; // fecha o arquivo out.close(); } Exemplo: programa que lê um inteiro, um valor em ponto flutuante e uma string do arquivo criado pelo programa anterior: #include <iostream.h> #include <fstream.h> void main (void) { // declaração das variáveis char ch; // guarda int i; // guarda float f; // guarda char str[80]; // guarda o o o a caractere lido inteiro lido número real lido string lida // abre um arquivo para leitura de nome Teste.txt ifstream in( "Teste.txt" ); if( !in ) { cout << "O arquivo não pode ser aberto!"; return 1; } in >> i; in >> f; in >> ch; in >> str; cout << i << " cout << str; " << f << " " << ch << endl; Manipulação de Arquivos Profª. Raquel Marcia Müller 3 // fecha o arquivo in.close(); } E/S Binárias Existem duas maneiras de se ler e escrever dados binários de e para um arquivo. Primeiro, pode-se escrever um byte usando-se a função membro put( ) e ler um byte com a função membro get( ). A função get( ) tem muitas formas, mas a versão mais usada é mostrada aqui. Protótipos das funções get( ) e put( ): istream &get( char &ch ); ostream &put( char &ch ) A função get() lê um único caracter do fluxo associado, coloca o valor em ch e retorna o fluxo. A função put() escreve ch para o fluxo e retorna o fluxo. Exemplo: programa que exibe o conteúdo de um arquivo na tela, usando a função get(). #include <iostream.h> #include <fstream.h> void main ( int argc, char *argv[] ) { // declaração das variáveis char ch; // guarda o caractere lido if( argc != 2 ) { cout << "Use: programa <nome do arquivo>" << endl; return 1; } // abre um arquivo para leitura ifstream in( argv[1] ); if( !in ) { cout << "O arquivo não pode ser aberto!"; return 1; } while( in ) { // in será zero quando eof (fim do arquivo) for encontrado in.get( ch ); cout << ch; } // fecha o arquivo in.close(); } Exemplo: programa que escreve uma string para um arquivo, usando a função put( ): #include <iostream.h> #include <fstream.h> void main ( void ) { char *p = "Alô a todos!"; // abre um arquivo para escrita ofstream out( "Test.txt" ); if( !out ) { cout << "O arquivo não pode ser aberto!"; return 1; } Manipulação de Arquivos Profª. Raquel Marcia Müller 4 while( *p ) out.put( *p++ ); // fecha o arquivo in.close(); } Detectando o EOF (Final do Arquivo) Pode-se saber quando o final de um arquivo é encontrado usando-se a função membro eof( ), que tem o protótipo a seguir: Protótipo da função eof( ): int eof( ); Ela retorna não zero quando o fim do arquivo é encontrado; caso contrário, retorna zero. Acesso Randômico No sistema de E/S do C++ é possível realizar acesso randômico usando-se as funções seekg( ) e seekp( ). As formas mais comuns dessas funções são mostradas abaixo. Protótipo das funções seekg() e seekp(): istream &seekg( streamoff offset, seek_dir origin ); ostream &seekp( streamoff offset, seek_dir origin ); Aqui, streamoff é um tipo definido em iostream.h capaz de conter o maior valor válido suportado por offset, seek_dir é uma enumeração que pode ter estes valores: ios::beg ios::cur ios::end Começo do arquivo Localização corrente Final do arquivo A função seek_g() move o ponteiro get (ponteiro de leitura), offset número de bytes a partir da origem especificada, que deve ter um dos três valores acima. A função seek_p() move o ponteiro put (ponteiro de escrita), offset número de bytes a partir da origem especificada, que deve ter um dos três valores acima. Exemplo: esse programa permite que seja especificado um nome de arquivo na linha de comando seguido pelo byte específico no arquivo que se deseja alterar. Então, escreve um "X" na localização especificada (usa a função seek_p()): #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main ( int argc, char *argv[] ) { if( argc != 3) { cout << "Use: programa <nome do arquivo> <byte>" << endl; return 1; } // abre um arquivo para escrita ofstream out( argv[1] ); if( !out ) { cout << "O arquivo não pode ser aberto!"; return 1; } out.seekp( atoi( argv[2] ), ios::beg ); out.put( 'X' ); Manipulação de Arquivos Profª. Raquel Marcia Müller 5 // fecha o arquivo out.close(); } Exemplo: esse programa usa a função seek_g() para exibir o conteúdo do arquivo, começando na localização especificada: #include <iostream.h> #include <fstream.h> #include <stdlib.h> void main ( int argc, char *argv[] ) { char ch; // armazena caracter lido if( argc != 3) { cout << "Use: programa <nome do arquivo> <byte>" << endl; return 1; } // abre um arquivo para leitura ifstream in( argv[1] ); if( !in ) { cout << "O arquivo não pode ser aberto!"; return 1; } in.seekg( atoi( argv[2] ), ios::beg ); while( in.get( ch )) cout << ch; // fecha o arquivo in.close(); } Lista de Programas 1. Programa Contale1.cpp // // // // // // Programa: contale1.cpp O Diálogo: Programa para contar a ocorrência de cada uma das letras A, B, ..., Z (ou suas minúsculas equivalentes a, b, ..., z) em um arquivo de texto. O vetor Frequencia indexado pelas letras A, ..., Z é usado para isto. Se Caracter é uma das 26 letras, Frequencia[Caracter] é o número de ocorrências de Caracter na linha do texto. // Declaração das bibliotecas utilizadas #include<iostream.h> // cin, cout #include<fstream.h> // ifstream #include<stdlib.h> // exit #include<ctype.h> // toupper // Declaração das constantes globais const unsigned int TAMMAX = 40; // Declaração dos Tipos typedef char string[50]; typedef enum{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z} Letra; typedef unsigned int VetorContaCar[26]; // Início da função principal void main(void) { // declaração das variáveis locais VetorContaCar Frequencia; // Freqüência das Letras ifstream ArquivoIn; ofstream ArquivoOut; Manipulação de Arquivos Profª. Raquel Marcia Müller 6 // declaração das funções. void AbreArq(ifstream &, ofstream &); void Inicializa(VetorContaCar); void LeDados(VetorContaCar, ifstream &); void ImprimeVetor(const VetorContaCar, ofstream&); void FechaArq(ifstream &, ofstream &); // Passo 1. Abra os arquivos AbreArq(ArquivoIn, ArquivoOut); // Passo 2. Inicialize o vetor Freqüência Inicializa(Frequencia); // Passo 3. Leia a Entrada LeDados(Frequencia, ArquivoIn); // Passo 4. Imprimir os resultados (vetor Frequencia) ImprimeVetor(Frequencia, ArquivoOut); // Passo 5. Feche o arquivo FechaArq(ArquivoIn, ArquivoOut); } // Fim da função principal // implementação das funções // Função: AbreArq // O Diálogo: Esta função abre um arquivo para leitura. void AbreArq(ifstream &ArquivoIn, ofstream &ArquivoOut) { // declaração das variáveis locais string NomeArquivoIn, NomeArquivoOut; // Leia o nome do arquivo de entrada cout << endl << "Entre com o nome do arquivo de entrada" << endl; cin.getline(NomeArquivoIn, TAMMAX); // Leia o nome do arquivo de saída cout << endl << "Entre com o nome do arquivo de saída" << endl; cin.getline(NomeArquivoOut, TAMMAX); // Abra o arquivo para leitura ArquivoIn.open(NomeArquivoIn, ios::in); // Abra o arquivo para escrita ArquivoOut.open(NomeArquivoOut, ios::out); // Verifique se o arquivo de entrada foi aberto com sucesso if (!ArquivoIn) { cerr << endl << "Arquivo de entrada não pode ser aberto" << endl; exit(1); } // Verifique se o arquivo de saída foi aberto com sucesso if (!ArquivoOut) { cerr << endl << "Arquivo de entrada não pode ser aberto" << endl; exit(1); } } // fim da função AbreArq // Função: Inicializa // O Diálogo: Esta função inicializa o vetor Freqüencia que armazenará as // freqüências dos caracteres no arquivo void Inicializa(VetorContaCar Frequencia) { // declaração das variáveis locais Letra Ch; Manipulação de Arquivos Profª. Raquel Marcia Müller 7 for (Ch=A; Ch <=Z; Ch = (Letra)(Ch+1)) { // Atribua 0 para a freqüência da i-ésima letra Frequencia[Ch] = 0; } } // fim da função inicializa // Função: LeDados // O Diálogo: Esta função le os dados de uma arquivo, conta a ocorrência dos // caracteres no arquivo e armazena no vetor Frequencia void LeDados(VetorContaCar Frequencia, ifstream &ArquivoIn) { // declaração das variáveis locais char Caracter; // Enquanto não chegar no final do arquivo leia os caracteres while(ArquivoIn.get(Caracter)) { // Transforme todos os caracteres para maiúsculas Caracter = toupper(Caracter); // Verifique se o caracter está entre A e Z if ((Caracter >= 'A') && (Caracter <= 'Z')) { // Caso verdadeiro incremente a freqüencia do caracter Frequencia[int(Caracter)-65]++; } } } // fim da função LeDados // Função: ImprimeVetor // O Diálogo: Esta função imprime um vetor void ImprimeVetor(const VetorContaCar Frequencia, ofstream &ArquivoOut) { // declaração das variáveis locais Letra Ch; // Imprima o cabeçalho ArquivoOut << "No texto computado, as letras A - Z ocorreram com a seguinte freqüência: " << endl; for (Ch = A; Ch <= Z; Ch = (Letra)(Ch+1)) { // Imprima a freqüência do i-ésimo caracter ArquivoOut << "Freqüência de " << char(Ch+65) << ": " << Frequencia[Ch] << endl; } } // fim da função ImprimeVetor // Função: FechaArq // O Diálogo: Esta função fecha um arquivo void FechaArq(ifstream &ArqIn, ofstream &ArqOut) { // Feche o arquivo de entrada ArqIn.close(); // Feche o arquivo de saída ArqOut.close(); } // fim da função FechaArq Exercício: Crie um arquivo A, com registros com campos de NOME e SALARIO. Depois crie um arquivo B, através da cópia dos registros de A.
Documentos relacionados
Standard Library -
• São utilizadas as classes ifstream e ofstream, para acesso de leitura e escrita de arquivos de dados respectivamente. • Declaração: // Arquivo de leitura – cria um fluxo de entrada ifstream arqui...
Leia maisArquivos Binários - Departamento de Computação e Matemática
Manipulação de Arquivos Binários Até agora vimos como criar arquivos de acesso seqüencial bem como realizar a busca por uma informação particular nesses arquivos. Arquivos seqüenciais são inadequad...
Leia maisC++ - Operações com arquivos Em C++, as classes iostream são
Compare o tamanho do arquivo apresentado pelo programa e o observado no explorer. A razão da diferença está no tratamento do ‘\n’. Modifique o programa para que o arquivo seja aberto em modo binári...
Leia maisArquivos Texto - Departamento de Computação e Matemática
fecha o arquivo saida.txt. Entretanto, o finalizador do objeto ofstream realiza essa operação automaticamente. Assim, é possível omitir completamente a linha 23 e mesmo assim o arquivo será fechado...
Leia mais