Baixe o app para aproveitar ainda mais
Prévia do material em texto
Ju d so n S an to s S an ti ag o MANIPULAÇÃO DE ARQUIVOS Estrutura de Dados I Frequentemente no computador a entrada de dados é feita pelo teclado e a saída de dados é feita em tela Introdução Programa Exibicao do time ----------------------------------------- Nome Gols Partidas ----------------------------------------- Bebeto (ex-Vasco) 760 900 Neto (ex-Corinthians) 102 400 Pele (ex-Santos) 1000 800 ----------------------------------------- Press any key to continue . . . Introdução As vezes a entrada de dados pelo teclado não é a melhor opção: Imagine usar o teclado para entrar com nome, preço e quantidade em estoque de 1000 produtos Programa Introdução As vezes a saída de dados pelo teclado não é a melhor opção: Seria conveniente gerar uma lista de compras de produtos fora de estoque em um arquivo Programa Introdução Hoje a maioria dos programas de computador trabalham com arquivos: Editores de texto criam documentos Bancos de dados criam, organizam e recuperam informações em arquivos Compiladores lêem o arquivo fonte de um programa e geram um arquivo executável Um arquivo é um conjunto de bytes armazenado em algum dispositivo Introdução O sistema operacional se encarrega de: Gerenciar os arquivos Saber a localização dos arquivos Guardar informações como tamanho, data de criação, última modificação, etc. Como programador estamos interessados em conectar um programa a um arquivo: Ler informações do arquivo Gravar informações no arquivo Introdução Para um programador os arquivos se dividem em duas categorias: Arquivos texto: uma sequência de bits em que um conjunto de n bits representa um caractere: Na codificação ASCII um caracatere são 8 bits Em Unicode um caractere são 16 bits Em UTF-8 um caractere tem de 8 a 32 bits 01000001 01110010 01110001 01110101 01101001 01110110 01101111 01110011 00100000 00001010 'A' 'r' 'q' 'u' 'i' 'v' 'o' 's' ' ' '\n' Arquivo texto na codificação ASCII 00000000000000000000000000001111 Introdução Para um programador os arquivos se dividem em duas categorias: Arquivos binários: uma sequência de bits em que um conjunto de n bits representa uma informação na sua representação nativa (inteira, ponto- flutuante, caractere, etc.) 00111110110000000000000000000000 01101001 01110110 01101111 01110011 00100000 0.375 'c' 'a' 's' 'a' '\0' 15 Arquivo binário float intchar [] Arquivos Texto São arquivos que guardam apenas texto (ex.: arquivos gerados no bloco de notas) 01101001 '0' '.' '3' '7' '5' Representação binária de 0.375 0 0111110 110000000000000000000000 mantissaexpoentesinal 01101001 01101001 01101001 01101001 Representação texto de 0.375 Saída em Arquivos Texto Para fazer a saída de dados em arquivos texto é preciso seguir os seguintes passos: Incluir o arquivo de cabeçalho fstream Criar um objeto do tipo ofstream Associar um objeto ofstream com um arquivo do disco usando a função open() Usar o operador de inserção << com o objeto (da mesma forma que se faz com cout) Fechar o arquivo com a função close() Saída em Arquivos Texto Incluir o arquivo de cabeçalho fstream: fornece acesso a classe ofstream Criar um objeto da classe ofstream. O arquivo de cabeçalho iostream fornece um objeto predefinido (cout) para a saída em tela. O arquivo de cabeçalho fstream não fornece um objeto predefinido para a saída em arquivo, é preciso criar um: #include <fstream> // entrada e saída de arquivos ofstream arqSaida; // um objeto ofstream ofstream fout; // outro objeto ofstream Saída em Arquivos Texto Associar um objeto ofstream com um arquivo do disco usando a função open() Usar o operador de inserção << com o objeto: arqSaida.open("pesca.txt"); // abre arquivo pesca.txt char arquivo[50]; // um vetor de caracteres cin >> arquivo; // nome definido pelo usuário fout.open(arquivo); // abre arquivo definido pelo usuário double wt = 125.8; arqSaida << wt; // escreve um número em pesca.txt char linha[81] = "Objetos são variáveis de uma classe"; fout << linha << endl; // escreva uma linha de texto Saída em Arquivos Texto Fechar o arquivo com a função close() O arquivo é fechado automaticamente no encerramento do programa, mas é uma boa prática de programação fechar arquivos abertos Isso permite reassociar o objeto a outro arquivo do disco arqSaida.close(); // fecha arquivo pesca.txt fout.close(); // fecha arquivo definido pelo usuário Saída em Arquivos Texto // escrevendo em arquivo texto #include <iostream> #include <fstream> using namespace std; int main() { char carro[50]; int ano; float precoN; flaot precoP; ofstream arqSaida; // cria objeto para saída arqSaida.open("carinfo.txt"); // associa com arquivo cout << "Entre com a marca e modelo do carro: "; cin.getline(carro, 50); cout << "Entre com o ano: "; cin >> ano; cout << "Digite o preço normal: "; cin >> precoN; precoP = 0.913 * precoN; Saída em Arquivos Texto // mostrando informações na tela cout << fixed; cout.precision(2); cout.setf(ios_base::showpoint); cout << "Marca e modelo: " << carro << endl; cout << "Ano: " << ano << endl; cout << "Preço normal: R$" << precoN << endl; cout << "Preço promocional: R$" << precoP << endl; // gravando informações no arquivo arqSaida << fixed; arqSaida.precision(2); arqSaida.setf(ios_base::showpoint); arqSaida << "Marca e modelo: " << carro << endl; arqSaida << "Ano: " << ano << endl; arqSaida << "Preço normal: R$" << precoN << endl; arqSaida << "Preço promocional: R$" << precoP << endl; arqSaida.close(); // fechando arquivo system("pause"); return 0; } Saída em Arquivos Texto Saída do programa: Arquivo carinfo.txt: Entre com a marca e modelo do carro: Ford Ka Entre com o ano: 2009 Digite o preço normal: 28576 Marca e modelo: Ford Ka Ano: 2009 Preço normal: R$28576.00 Preço promocional: R$26089.89 Marca e modelo: Ford Ka Ano: 2009 Preço normal: R$28576.00 Preço promocional: R$26089.89 Saída em Arquivos Texto O método open(): Cria um novo arquivo, se ele não existir Sobrescreve o arquivo, se ele existir A abertura de um arquivo pode falhar caso o arquivo utilizado seja um arquivo de acesso restrito: Por exemplo, um arquivo já aberto em outro programa ou um arquivo protegido arqSaida.open("carinfo.txt"); // associa com arquivo Leitura de Arquivos Texto Para fazer a leitura de arquivos texto é preciso seguir os seguintes passos: Incluir o arquivo de cabeçalho fstream Criar um objeto do tipo ifstream Associar um objeto ifstream com um arquivo do disco usando a função open() Usar o operador de extração >>, o método get() ou getline() com o objeto ifstream Fechar o arquivo com a função close() Leitura de Arquivos Texto Incluir o arquivo de cabeçalho fstream: fornece acesso a classe ifstream Criar um objeto da classe ifstream. O arquivo de cabeçalho iostream fornece um objeto (cin) para a entrada de dados pelo teclado O arquivo de cabeçalho fstream não fornece um objeto predefinido para a entrada de dados pelo arquivo, é preciso criar um: #include <fstream> // entrada e saída de arquivos ifstream arqEntrada; // um objeto ifstream ifstream fin; // outro objeto ifstream Leitura de Arquivos Texto Associar um objeto ifstream com um arquivo do disco usando a função open() Usar o operador de extração >>, o método get() ou getline() com o objeto: arqEntrada.open("boliche.txt"); // abre arquivo boliche.txt char arquivo[50]; // um vetor de caracteres cin >> arquivo; // nome definido pelo usuário fin.open(arquivo); // abre arquivo definido pelo usuário double wt; arqEntrada >> wt; // lê um número de boliche.txt char linha[81]; fin.getline(linha, 81); // lê uma linha de texto do arquivo Leitura de Arquivos Texto Fechar o arquivo com a função close() O arquivo é fechado automaticamente no encerramento do programa, mas é uma boa prática de programação fechar arquivos abertos Isso permite reassociar o objeto a outro arquivo do disco arqEntrada.close(); // fecha arquivo boliche.txt fin.close(); // fecha arquivo definido pelo usuário Leitura de Arquivos Texto Se o arquivo não existir no disco, todas as tentativas de leitura do arquivo vão falhar A melhor forma de checar se um arquivo foi aberto corretamente é através do método is_open() arqEntrada.open("boliche.txt"); if (!arqEntrada.is_open()) { cout << "A abertura do arquivo falhou!" << endl; exit(EXIT_FAILURE); } Leitura de Arquivos Texto // lendo arquivos texto #include <iostream> #include <fstream> using namespace std; const int TAM = 60; int main() { char arquivo[TAM]; ifstream arqEntrada; // cria objeto para leitura de arquivo cout << "Digite nome do arquivo: "; cin.getline(arquivo, TAM); arqEntrada.open(arquivo); // associa com arquivo do disco if (!arqEntrada.is_open()) // a abertura do arquivo falhou { cout << "A abertura do arquivo " << arquivo << " falhou!" << endl; cout << "Programa encerrando...\n"; exit(EXIT_FAILURE); } Leitura de Arquivos Texto double valor; double soma = 0.0; // soma dos itens int cont = 0; // número de itens lidos arqEntrada >> valor; // lê primeiro valor while (arqEntrada.good()) // enquanto a entrada for boa e não eof { ++cont; // mais um item lido soma += valor; // acumula valores lidos arqEntrada >> valor; // lê próximo valor } if (arqEntrada.eof()) cout << "Fim de arquivo alcançado.\n"; else if (arqEntrada.fail()) cout << "Tipo incorreto de dado na entrada.\n"; else cout << "Entrada encerrada por razão desconhecida.\n"; Leitura de Arquivos Texto if (cont == 0) cout << "Nenhum valor processado.\n"; else { cout << "Itens lidos: " << cont << endl; cout << "Soma: " << soma << endl; cout << "Média: " << soma / cont << endl; } arqEntrada.close(); // fecha o arquivo system("pause"); return 0; } Leitura de Arquivos Texto Arquivo "pontos.txt": Saída do programa: 18 19 18.5 13.5 14 16 19.5 20 18 12 18.5 17.5 Digite nome do arquivo: pontos.txt Fim de arquivo alcançado. Itens lidos: 12 Soma: 204.5 Média: 17.0417 Modos de Abertura O modo de abertura do arquivo descreve como o arquivo será usado: Apenas escrita de dados Apenas leitura de dados Leitura e escrita de dados Junção de dados Ao abrir o arquivo pode-se passar um segundo argumento com o modo de abertura arqEntrada.open("boliche.txt", ios_base::in); Modos de Abertura A tabela abaixo lista as constantes que podem ser usadas para o modo de abertura: Constante Significado ios_base::in Abre arquivo para leitura ios_base::out Abre arquivo para escrita ios_base::ate Vai pro fim do arquivo ao abrí-lo ios_base::app Junta ao final do arquivo ios_base::trunc Limpa arquivo, se ele existir Ios_base::binary Arquivo binário Modos de Abertura Omitindo o modo de abertura do arquivo faz com que sejam usados os valores padrão: Ifstream Ofstream Para escrever dados sem apagar o arquivo: arqEntrada.open("boliche.txt", ios_base::in); arqSaida.open("pesca.txt", ios_base::out | ios_base::trunc); ofstream arqSaida; arqSaida.open("append.txt", ios_base::out | ios_base::app); Arquivos Binário São arquivos que guardam a informação em sua representação binária (ex.: Word 2003) 01101001 '0' '.' '3' '7' '5' Representação binária de 0.375 0 0111110 110000000000000000000000 mantissaexpoentesinal 01101001 01101001 01101001 01101001 Representação texto de 0.375 Arquivos Binários A entrada e saída de arquivos binários é usualmente feita com o uso de registros Para salvar o registro num arquivo binário: struct planeta { char nome[20]; // nome do planeta double populacao; // número de habitantes double gravidade; // aceleração da gravidade }; planeta pl = {"Terra", 6820400000, 9.81}; ofstream fout; fout.open("planetas.dat", ios_base::out | ios_base::binary); fout.write( (char*) &pl, sizeof pl); Arquivos Binários O método write() copia uma quantidade de bytes de dados da memória para um arquivo A instrução vai para o endereço de pl e copia 36 bytes (o tamanho do registro pl) para o arquivo associado a fout (planetas.dat) A conversão do endereço do registro para um ponteiro para char é necessária para usar write() ofstream fout; fout.open("planetas.dat", ios_base::out | ios_base::binary); fout.write( (char*) &pl, sizeof pl); Arquivos Binários Para recuperar a informação gravada no arquivo é preciso usar o mesmo resgistro Para ler o registro de um arquivo binário: struct planeta { char nome[20]; // nome do planeta double populacao; // número de habitantes double gravidade; // aceleração da gravidade }; planeta nv; ifstream fin; fin.open("planetas.dat", ios_base::in | ios_base::binary); fin.read( (char*) &nv, sizeof nv); Arquivos Binários // entrada e saída em arquivos binários #include <iostream> #include <fstream> using namespace std; struct planeta { char nome[20]; // nome do planeta double populacao; // número de habitantes double gravidade; // aceleração da gravidade }; int main() { planeta pl; ifstream fin; // cria objeto para leitura de arquivo fin.open("planetas.dat", ios_base::in | ios_base::binary); // continua Arquivos Binários if (fin.is_open()) // se o arquivo foi aberto sem erros { cout << "Aqui esta o conteúdo do arquivo:" << endl; while (fin.read((char *) &pl, sizeof pl)) { cout << pl.nome << " " << pl.populacao << " " << pl.gravidade << endl; } fin.close(); } // acrescenta mais dados ofstream fout; fout.open("planetas.dat", ios_base::out | ios_base::app | ios_base::binary); if (!fout.is_open()) { cout << "Arquivo não pode ser aberto!" << endl; exit(EXIT_FAILURE); } // continua Arquivos Binários cout << "\nNome do planeta: "; cin >> pl.nome; cout << "Populacao: "; cin >> pl.populacao; cout << "Gravidade: "; cin >> pl.gravidade; fout.write((char *) &pl, sizeof pl); fout.close(); fin.open("planetas.dat", ios_base::in | ios_base::binary); if (fin.is_open()) { cout << "\nAqui esta o conteúdo do arquivo:" << endl; while (fin.read((char *) &pl, sizeof pl)) { cout << pl.nome << " " << pl.populacao << " " << pl.gravidade << endl; } fin.close(); } system("pause"); return 0; } Arquivos Binários Saída do programa: Aqui esta o conteudo do arquivo: Terra 6820400000 9.81 Marte 2 9.81 Venus 0 6.53 Mercurio 0 8.88 Nome do planeta: Plutao Populacao: 0 Gravidade: 3.10 Aqui esta o conteudo do arquivo: Terra 6820400000 9.81 Marte 2 9.81 Venus 0 6.53 Mercurio 0 8.88 Plutao 0 9.20 Press any key to continue . . . Conclusão Entrada e saída de dados em arquivos é um recurso utilizado pela maioria dos programas Dados podem ser armazenados em: Arquivos texto: podem ser lidos por qualquer editor de texto e são altamenteportáveis Arquivos binários: são mais precisos para números, as operações de leitura e escrita são mais rápidas e geralmente ocupa menos espaço
Compartilhar