MC-102 Algoritmos e Programação de Computadores Prof. Ariel Vargas Unicamp Arquivos Binários
Arquivos Arquivos Texto Podem ser manipulados por um editor de texto comum Os dados são gravados como caracteres de 8 bits (1 byte). Ex: O número 12345678 ocupa 8 bytes, ou seja, 64 bits Arquivos Binários Dados são gravados na forma binária Costumam ser mais compactos. Ex: O número 12345678 ocupa 4 bytes (considerado-se uma máquina na qual um número inteiro é representado por 32 bits) Indicados para armazenar grandes quantidades de valores numéricos
Arquivos binários, qual a vantagem?
Como Manipular Arquivos Binários? Da mesma forma que um arquivo texto: É preciso abrir o arquivo antes de realizar leitura/escrita É preciso fechar o arquivo após realizar leitura/escrita
Arquivos Binários Para abrir e fechar uma arquivo binário usa-se, da mesma forma, as funções: (não muda nada!!!) Abrir um arquivo: ponteiro_para_arquivo = fopen (nome_arquivo, modo_abertura); Fechar um arquivo: fclose (ponteiro_para_arquivo);
Arquivos Binários Alguns modos de abertura: (tem um b agora) rb - abre arquivo binário para leitura wb - cria arquivo binário para gravação, eliminando o conteúdo anterior, se houver ab - abre ou cria um arquivo binário para gravação em seu final r+b - abre arquivo binário para leitura e gravação no início w+b - cria arquivo binário para leitua/gravação no início a+b - abre ou cria arquivo binário para leitura no início e gravação no final
Arquivos Binários Ler dados de um arquivo binário: fread (endereco_da_variavel, tamanho_tipo_de_dado, numero_elementos, ponteiro_para_arquivo); Ex: Int n; fread(&n, sizeof(int), 1, f); endereco_memoria, tamanho_tipo_de_dado, numero_elementos, ponteiro_para_arquivo
Arquivos Binários Escrever dados em um arquivo binário: fwrite (endereco_da_variavel, tamanho_tipo_de_dado, numero_elementos, ponteiro_para_arquivo); Ex: Int n = 10; fwrite(&n, sizeof(int), 1, f); endereco_memoria, tamanho_tipo_de_dado, numero_elementos, ponteiro_para_arquivo
Lendo e escrevendo Vetores de um arquivo binário #include<stdio.h> #include<stdlib.h> int main(){ int i, v[20] = {0, 1, 2, 3,4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; int v2[20]; FILE *f; //ponteiro para arquivo int n = 20; f = fopen ("vetor.bin", "wb"); //crio o arquivo para gravação fwrite(&n,sizeof(int),1,f); //gravo n na primeira posição do arquivo for (i=0;i<n;i++) fwrite(&v[i],sizeof(int),1,f); //gravo o vetor posição a posição fclose(f); //fecho o arquivo f = fopen ("vetor.bin", "rb"); //abro novamente para leitura fread(&n,sizeof(int),1,f); //leio a primeira posição q contem a quantidade de elementos do vetor printf("%d\n",n); //imprimo a quantidade na tela for (i=0;i<n;i++){ fread(&v2[i],sizeof(int),1,f); //leio cada posição do vetor e armazeno em v2 na tela printf("%d ",v2[i]) ; //imprimo cada posição de v2 } }
E daí... Nenhuma vantagem até agora...
Lendo e escrevendo Vetores de um arquivo binário #include<stdio.h> #include<stdlib.h> int main(){ int i, v[20] = {0, 1, 2, 3,4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; int v2[20]; FILE *f; //ponteiro para arquivo int n = 20; f = fopen ("vetor2.bin", "w+b"); //crio o arquivo para gravação e leitura fwrite(&n,sizeof(int),1,f); //gravo n na primeira posição do arquivo fwrite(&v,sizeof(v),1,f); //gravo o vetor todo de uma vez rewind(f); //volto o ponteiro para a primeira posição do arquivo fread(&n,sizeof(int),1,f); //leio a primeira posição q contem a quantidade de elementos do vetor printf("%d\n",n); //imprimo a quantidade na tela fread(&v2,sizeof(v),1,f); //leio o vetor todo e armazeno em v2 for (i=0;i<n;i++){ printf("%d ",v2[i]) ; } } Alternativa a leitura do vetor de uma só vez fread(&v2,sizeof(int),n,f);
Matrizes E como seria se eu precisasse trabalhar com uma matriz em um arquivo?
Lendo e escrevendo Matrizes em um arquivo binário #include<stdio.h> #include<stdlib.h> int main(){ int i,j, m[4][5] = {0,1,2,3,4, 5,6,7,8,9, 10,11,12,13,14, 15,16,17,18,19}; int m2[4][5]; FILE *f; //ponteiro para arquivo int l = 4; int c = 5; f = fopen ("mat.bin", "w+b"); //crio o arquivo para gravação e leitura fwrite(&l,sizeof(int),1,f); fwrite(&c,sizeof(int),1,f); //gravo l na primeira posição do arquivo //gravo c na segunda posição do arquivo fwrite(&m,sizeof(m),1,f); //gravo a matriz toda de uma vez
Lendo e escrevendo Matrizes em um arquivo binário rewind(f); //volto o ponteiro para a primeira posição do arquivo fread(&l,sizeof(int),1,f); fread(&c,sizeof(int),1,f); //leio l da primeira posição do arquivo //leio c da segunda posição do arquivo printf("matriz m[%d][%d] =\n",l,c); //imprimo o cabeçalho da matriz na tela fread(&m2,sizeof(m),1,f); //leio a matriz toda e armazeno em m2 } for (i=0;i<l;i++){ for (j=0;j<c;j++) printf("%d ",m2[i][j]); printf("\n"); } //imprimo cada posição de m2 na tela
Registros E com registros?
Registros Exemplo leitura...: typedef struct { char nome[20]; float media; }tipo_aluno; tipo_aluno a; tipo_aluno vet[100]; fread(&a,sizeof(tipo_aluno),1,f); //lendo um registro; fread(&vet,sizeof(tipo_aluno),100,f); //lendo o vetor todo fread(&vet,sizeof(vet),1,f); //lendo o vetor todo;
Registros Exemplo escrita: typedef struct { char nome[20]; float media; }tipo_aluno; tipo_aluno a; tipo_aluno vet[100]; fwrite(&a,sizeof(tipo_aluno),1,f); //escrevendo um registro; fwrite(&vet,sizeof(tipo_aluno),100,f); // escrevendo o vetor todo fwrite(&vet,sizeof(vet),1,f); // escrevendo o vetor todo;
Como acessar um dado ou registro sem precisar ler o arquivo seqüencialmente? Função: fseek (ponteiro_para_arquivo, posicao_relativa, marcação); Posiciona o ponteiro para arquivo binário, relativamente à marcação indicada: SEEK_SET início do arquivo SEEK_CUR posição corrente do arquivo SEEK_END final do arquivo
Exemplo fseek e registros #include<stdio.h> #include<stdlib.h> typedef char Disc[5]; //definindo um tipo de dado novo typedef struct{ int RA; char nome[30]; Disc matriculas[6]; //vetor do novo tipo definido Disc float CR; }tipo_reg_aluno;
Exemplo fseek e registros int main(){ FILE *f; tipo_reg_aluno Vet[2] = { {12436, "Maria", {"MC102", "MA141", "F 128", "F 129"}, 0.0}, {12232, "Joà o", {"MC202", "MA211", "F 228", "F 229"}, 0.8} }; tipo_reg_aluno aux; f = fopen ("dados_aluno.bin", "wb"); //crio o arquivo fwrite(vet, sizeof(tipo_reg_aluno), 2, f); //gravo o vetor inteiro no arquivo fclose(f); //fecho o arquivo
Exemplo fseek e registros f = fopen ("dados_aluno.bin", "r+b"); //abro novamente para alterar fseek(f, 2 * sizeof(tipo_reg_aluno), SEEK_SET); //posiciono o ponteiro no segundo registro fread(&aux, sizeof(tipo_reg_aluno), 1, f); //leio o registro e guardo em aux aux.ra = 61122; //altero o ra do aluno fseek(f, 2 * sizeof(tipo_reg_aluno), SEEK_SET); //posiciono o ponteiro denovo no registro fwrite(&aux, sizeof(tipo_reg_aluno), 1, f); //Sobrescrevo o registro atualizado no arquivo fclose(f); //fecho o arquivo
Exercício 1 Dado o arquivo numeros.bin que possui em sua primeira posição um inteiro que indica a quantidade de elementos de um vetor e nas demais posições valores inteiros: Ex: 100 10 5 15 21 3 99 101 458 22... a) Escreva um programa que leia os elementos do arquivo e guarde-os em um vetor; b) Verifique se cada número é primo; c) Armazene os números primos em um novo arquivo binário que deve ter o seguinte formato: na primeira posição a quantidade de primos Nas demais posições os números primos Utilize a função ehprimo para verificar se um número é primo para verificar se cada número é primo
Exercício 1 // --------------------função eh primo------------------------------------------ int ehprimo (int n){ // n é o parâmetro de entrada int resto,i, primo=1; //define primo como verdadeiro for (i=2;i<n;i++){ // divide o n por todos os anteriores resto = n % i; if (resto == 0) primo=0; } if (primo) return 1; // retorna verdadeiro, é primo else return 0; // retorna falso, não é primo } //-------------------------------------------------------------------------------
Exercício 2 Baseando-se no exemplo Exemplo fseek e registros altere o programa para que ele atualize o CR de uma aluno informado pelo usuário. O usuário informa o RA do aluno e o novo CR. O programa deve localizar o aluno pelo RA e atualizar o registro no arquivo.