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 Programação de Computadores 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 . . . 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 Entrada Introdução As vezes a saída de dados na tela não é a melhor opção: Seria conveniente gerar uma lista de compras de produtos fora de estoque em um arquivo Programa Saída Introdução Hoje em dia quase a totalidade dos programas de computador trabalham com arquivos: Editores de texto, planilhas e apresentações criam documentos em arquivos Editores de imagens, vídeos e sons criam, organizam e guardam 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 para: 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 representam um caractere: Na codificação ASCII um caracatere são 8 bits Em Unicode um caractere tem de 8 a 32 bits Existem várias codificações (UTF-8, UTF-16, UTF-32) 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 representam 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 [] Introdução Diferença entre arquivos texto e binário: 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 Introdução A entrada e saída de arquivos em C++ é muito parecida com a entrada e saída no console Programa Console Arquivo Console ArquivoSaídaEntrada Entrada e Saída Quando utiliza-se cin para ler dados, o programa vê a entrada como uma série de bytes (caracteres): Suponha que você digite a seguinte entrada: A entrada é um conjunto de caracteres (bytes) armazenados no buffer de entrada 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' 38.5 19.2 Entrada e Saída Cada byte é interpretado como um código de um caractere (tabela ASCII) Não importa o tipo de destino, a entrada é feita com o tipo caractere, ou seja, texto cin tem a responsabilidade de traduzir o texto para o tipo da variável utilizada 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' cin >> total; Entrada e Saída Entrada usando uma variável tipo char: O primeiro caractere da entrada é atribuído para a variável, nenhuma tradução acontece 38.5 19.2 char ch; cin >> ch; 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' 00110011 ch Entrada e Saída Entrada usando uma variável tipo int: A leitura é feita até encontrar o primeiro caractere que não é um dígito 38.5 19.2 int n; cin >> n; 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' n= 00000000 00000000 00000000 00100110'3' '8' 38 Entrada e Saída Entrada usando uma variável tipo float: A leitura é feita até encontrar um caractere que não faz parte de um ponto-flutuante 38.5 19.2 float x; cin >> x; 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' x= 00000001 00000000 00000001 10000001'3' '8' '.' '5' 38.5 Entrada e Saída Entrada usando um vetor de caracteres: A leitura é feita até encontrar um caractere em branco, tabulação ou nova linha 38.5 19.2 char nome[50]; cin >> nome; 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' nome='3' '8' '.' '5' "38.5" 00110011 00111000 00101110 00110101 00000000 Entrada e Saída Entrada usando um vetor de caracteres: Usando a função getline, a entrada é lida até o caractere de nova linha 38.5 19.2 char nome[50]; cin.getline(nome, 50); 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101 '3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n' nome "38.5 19.2" 00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00000000 Entrada e Saída Em resumo, o texto digitado pelo teclado é recebido sempre em forma de texto e depois convertido para o tipo apropriado Um arquivo texto se assemelha muito ao buffer do teclado, isto é, ele é composto por uma seqüência de caracteres Um arquivo binário armazena mais que texto: Planilhas armazenam dados em formato numérico Editores de texto armazenam formatação, fontes, imagens, impressoras, etc. Saída em Arquivos Texto Para usar cout num programa é necessário: Incluir o arquivo de cabeçalho iostream Define uma classe ostream para manipular a saída Declara um objeto da classe ostream chamado cout Considerar que os objetos estão definidos no espaço de nomes std #include <iostream> using namespace std; // ou using std::cout; Saída em Arquivos Texto Para usar cout num programa é necessário: Usar cout com o operador de inserção << para mostrar vários tipos de dados diferentes Usar cout.setf() e cout.precision() para modificar a forma de impressão dos dados char ch = 'M'; float num = 35.4f; cout << ch; cout << num; float tax = 31.28062; cout.setf(ios_base::fixed, ios_base::floatfield); cout.precision(2); cout << tax; Saída em Arquivos Texto Fazer a saída em arquivos é semelhante: Incluiro arquivo de inclusão fstream Define uma classe ofstream para manipular a saída 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 ofstream Fechar o arquivo com a função close() Saída em Arquivos Texto O arquivo de inclusão fstream não fornece um objeto predefinido, é preciso criar um: E associá-lo com um arquivo do disco: Para usá-los desta forma: ofstream fout; // um objeto ofstream fout.open("pesca.txt"); // fout usado para escrever em 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; fout << 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 // escrevendo em arquivo texto #include <iostream> #include <fstream> using namespace std; int main() { char carro[50]; int ano; float precoN; // preço normal flaot precoP; // preço promocional ofstream fout; // cria objeto para saída fout.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 << "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 fout << fixed; fout.precision(2); fout << "Marca e modelo: " << carro << endl; fout << "Ano: " << ano << endl; fout << "Preço normal: R$" << precoN << endl; fout << "Preço promocional: R$" << precoP << endl; fout.close(); 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 do S.O. fout.open("carinfo.txt"); // associa com arquivo Leitura de Arquivos Texto Para usar cin num programa é necessário: Incluir o arquivo de inclusão iostream Define uma classe istream para manipular a entrada Declara um objeto da classe istream chamado cin Considerar que estes objetos estão definidos no espaço de nomes std #include <iostream> using namespace std; //ou using std::cin; Leitura de Arquivos Texto Para usar cin num programa é necessário: Usar cin com o operador de extração >> para ler vários tipos de dados diferentes Usar cin.get() para ler caracteres individuais ou cin.getline() para ler uma linha por vez char ch; float num; cin >> ch; cin >> num; char ch; char nome[30]; cin.get(ch); cin.getline(nome, 30); Leitura de Arquivos Texto A leitura de arquivos é muito semelhante: Incluir o arquivo de cabeçalho fstream Define uma classe ifstream para manipular a entrada 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 O arquivo de inclusão fstream não fornece um objeto predefinido, é preciso criar um: E associá-lo com um arquivo do disco: Para usá-los desta forma: ifstream fin; // outro objeto ifstream fin.open("boliche.txt"); // fin usado para ler 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; fin >> wt; // lê um número de boliche.txt char linha[81]; fin.getline(linha, 81); // lê uma linha de texto Leitura de Arquivos Texto Se o arquivo não existir no disco, todas as tentativas de uso do objeto ifstream vão falhar A melhor forma de checar se um arquivo foi aberto corretamente é através do método is_open() fin.open("boliche.txt"); if (!fin.is_open()) { cout << "A abertura do arquivo falhou!" << endl; system("pause"); 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 fin; // cria objeto para leitura de arquivo cout << "Digite nome do arquivo: "; cin.getline(arquivo, TAM); fin.open(arquivo); // associa com arquivo do disco if (!fin.is_open()) // a abertura do arquivo falhou { cout << "A abertura do arquivo " << arquivo << " falhou!" << endl; cout << "Programa encerrando.\n"; system("pause"); exit(EXIT_FAILURE); } Leitura de Arquivos Texto double valor; double soma = 0.0; // soma dos itens int cont = 0; // número de itens lidos fin >> valor; // lê primeiro valor while (fin.good()) // enquanto a entrada for boa e não eof { ++cont; // mais um item lido soma += valor; // acumula valores lidos fin >> valor; // lê próximo valor } if (fin.eof()) cout << "Fim de arquivo alcançado.\n"; else if (fin.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; } fin.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 Ao abrir um arquivo pode-se passar um segundo argumento com o modo de abertura O modo de abertura do arquivo permite configurar como o arquivo será aberto: Escrita de dados Leitura de dados Adição de dados Modo texto ou binário fin.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::app Acrescenta ao final do arquivo ios_base::trunc Limpa arquivo, se ele existir ios_base::binary Cria arquivo binário ios_base::nocreate Falha se arquivo não existir ios_base::noreplace Falha se arquivo já existir 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: fin.open("boliche.txt", ios_base::in); fout.open("pesca.txt", ios_base::out |ios_base::trunc); ofstream fout; fout.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 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 p = {"Terra", 6820400000, 9.81}; ofstream fout; fout.open("planetas.dat", ios_base::out | ios_base::binary); fout.write( (char*) &p, sizeof p); Arquivos Binários O método write() copia uma quantidade de bytes da memória para um arquivo A instrução vai para o endereço de p e copia 36 bytes (o tamanho do registro planeta) 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*) &p, sizeof p); Arquivos Binários Para recuperar a informação gravada no arquivo é preciso usar o mesmo registro 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 p; 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 *) &p, sizeof p)) { cout << p.nome << " " << p.populacao << " " << p.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; system("pause"); exit(EXIT_FAILURE); } // continua Arquivos Binários cout << "\nNome do planeta: "; cin >> p.nome; cout << "Populacao: "; cin >> p.populacao; cout << "Gravidade: "; cin >> p.gravidade; fout.write((char *) &p, sizeof p); 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 *) &p, sizeof p)) { cout << p.nome << " " << p.populacao << " " << p.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 Conclusão Entrada e saída de dados em arquivos é um recurso muito utilizado em programas Os dados podem ser armazenados em: Arquivos texto: podem ser lidos por qualquer editor de texto e são altamente portáveis Arquivos binários: são mais precisos para armazenar números ponto-flutuante, as operações de leitura e escrita são mais rápidas, mas geralmente ocupam mais espaço
Compartilhar