Buscar

Aula 23 - arq bin aleatorio

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

A23: Arquivos binários (2), 
acesso aleatório
Algoritmos e Programação
Julio Toss
jtoss@inf.ufrgs.br
INF01202 – Algoritmos e Programação, 2018/01, Turmas G, H, K e L
*baseado no material da prof. Mariana e do prof. Marcelo Walter 
Atenção:
O material aqui contido não substitui a leitura do livro texto e é incompleto sem a 
apresentação do professor em aula.
2
Aula passada
Arquivos em C
- I/O usa conceito de stream de dados
- Ponteiro do tipo * FILE 
- independente de dispositivos
- Operações são “bufferizadas”
- binário vs. texto
Armazenamento de arquivos binários*:
*Assumimos que um arquivo binário contém um conjunto 
de informações de um mesmo tipo, simples ou estruturado
Manipulação de arquivos:
3
Aula passada: utilizando arquivos em C
A utilização de arquivos em C (binários ou arquivo texto) envolve os seguintes passos:
1 Declaração do arquivo através de um ponteiro (do tipo específico FILE *)
FILE *point_arq;
2 Abertura do arquivo, onde o ponteiro declarado é associado fisicamente ao arquivo 
externo através de um comando específico (fopen)
point_arq = fopen(“nome_do_arquivo”, “modo_de_abertura”)
3 Operações com arquivos, através de funções de manipulação de arquivos (leitura, 
escrita, dentre outras). Todas estas funções são aplicadas ao ponteiro associado ao 
arquivo.
4 Fechamento do arquivo, através de um comando específico (fclose)
fclose(point_arq); 4
Aula passada: utilizando arquivos em C
A utilização de arquivos em C (binários ou arquivo texto) envolve os seguintes passos:
1 Declaração do arquivo através de um ponteiro (do tipo específico FILE *)
FILE *point_arq;
2 Abertura do arquivo, onde o ponteiro declarado é associado fisicamente ao arquivo 
externo através de um comando específico (fopen)
point_arq = fopen(“nome_do_arquivo”, “modo_de_abertura”)
3 Operações com arquivos, através de funções de manipulação de arquivos (leitura, 
escrita, dentre outras). Todas estas funções são aplicadas ao ponteiro associado ao 
arquivo.
4 Fechamento do arquivo, através de um comando específico (fclose)
fclose(point_arq); 5
Aula passada: manipulação de arquivos
6
Para pensar em casa...
Escreva um programa que lê os dados de estudantes do ensino médio que prestaram ENEM. O seu programa 
deve armazenar numa struct os dados: nome do aluno (max 60 caracteres), a idade do aluno e a média final 
que o aluno obteve (inteiro entre 0 e 100, não precisa fazer validação). Leia os dados e armazene num arquivo 
binário cujo nome será lido do usuário. O programa deve parar de ler dados quando o usuário digitar a string 
“Sair” para o nome do aluno. Após a leitura e armazenamento dos dados no arquivo, o programa deve solicitar 
ao usuário uma média qualquer e o programa deve listar o nome e média de todos os alunos que tiveram média 
maior ou igual à média informada. Esta informação deve ser obtida a partir da leitura do arquivo salvo. Abaixo 
exemplo de execução:
7
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STR_MAXLEN 60
typedef struct str_aluno
{
char nome[STR_MAXLEN+1];
int idade;
int media;
}aluno_t;
int main( )
{
aluno_t buffer;
FILE *arq;
char nome[16];
int media;
printf("Nome do arquivo: ");
scanf("%s",nome);
 
if(!(arq = fopen(nome,"wb"))) 
 printf("Erro criacao");
else{
//continua...
8
 do{ //coleta dados do usuário e grava no arquivo
 fflush(stdin);
 printf("\nNome: ");
 fgets(buffer.nome, STR_MAXLEN, stdin);
 buffer.nome[ strlen(buffer.nome)-1 ] = '\0'; //remove '\n'
 if ( strcmp(buffer.nome," Sair") != 0 ) {
 printf("Idade: ");
 scanf("%d",&buffer.idade);
 printf("Media: ");
 scanf("%d",&buffer.media);
 if (fwrite(&buffer,sizeof(aluno_t),1,arq) != 1)
 printf("Erro de escrita!\n"); 
 }
 
 }while(strcmp(buffer.nome,"Sair"));
 fclose(arq); //fecha arquivo
 }//fecha else
 //continua...
9
 //continuando, na main()...
 
 printf("Entre com a média para busca: ");
 scanf("%d",&media);
 if(!(arq = fopen(nome,"rb")))
 printf("Erro abertura!");
 else{
 printf("Listando todos os alunos com media acima de %d\n ",media);
 
while(!feof(arq)) { //para no fim do arquivo
 if(fread(&buffer,sizeof(aluno_t),1,arq) == 1) {
 if(buffer.media > media)
 printf("\nAluno %s: Media %d\n",buffer.nome,buffer.media);
 }
 }
 fclose(arq); //fecha
 }
 
return 0;
}//fecha main
Arquivos Binários (2),
acesso aleatório
10
Arquivos: leitura e gravação sequencial
11
Definição: acessa uma posição sem percorrer sequencialmente o conteúdo que 
antecede o conteúdo desejado.
Motivações:
- a posição desejada de leitura ou escrita pode não ser coincidente com a 
posição corrente do arquivo válida em um certo momento.
- a posição corrente de leitura ou escrita pode ser alterada para qualquer 
posição do arquivo.
Arquivos binários: acesso aleatório
12
Três funções de manipulação permitem modificar a posição corrente no arquivo:
rewind() - aula passada
fseek()
ftell() 
Funções de manipulação de posição
13
Três funções de manipulação permitem modificar a posição corrente no arquivo:
rewind() - aula passada
fseek()
ftell() 
Funções de manipulação de posição
14
Três funções de manipulação permitem modificar a posição corrente no arquivo:
rewind() - aula passada
fseek()
ftell() 
Funções de manipulação de posição
15
Exemplo aula passada: dado um arquivo binário com dados de atletas 
organizados em um tipo estrutura (com nome, altura e idade), ler o 
nome de um atleta e procurar seus dados no arquivo, imprimindo-os
// na main...
do {
rewind(arq); // reposiciona registro corrente no início do arquivo.
encontrado = 0; //indica não encontrado (ainda)
printf("Nome do atleta procurado: ");
fgets(procurado, MAX_STRLEN, stdin);
while(!feof(arq) && !encontrado) //para qdo. acha ou no fim do arquivo
if(fread(&buffer,sizeof(atleta_t),1,arq) == 1)
if( strcmp(buffer.nome, procurado) == 0) {
printf("\nAltura de %s: %.2fm",procurado,buffer.altura);
encontrado = 1; // indica que encontrou
}
}
if (!encontrado) printf("\nAtleta nao foi localizado.");
printf("\n1-BuscarOutro, 2-Encerrar\n");
scanf("%i",&op);
} while(op != 2);
// continua...
Funções de manipulação de posição - fseek( )
16
http://en.cppreference.com/w/c/io/fseek
Funções de manipulação de posição - fseek( )
17
Exemplo: dada um arquivo binário com dados de atletas (aula anterior) imprimir na tela os dados do terceiro 
atleta cadastrado.
int main() {
 atleta_t buffer;
 FILE *arq; //declaração do ponteiro para arquivo
 char nome[STR_MAXLEN];
 printf("Nome do arquivo (maximo %d caracteres): ", STR_MAXLEN-1);
 fgets(nome, STR_MAXLEN, stdin);
nome[ strlen(nome)-1 ] = '\0'; // remove '\n' lido
 if( !(arq = fopen(nome,"r+b")) ) // leitura e escrita (os dados permanecem)
 printf("Erro criacao");
 else {
// continua...
//continua…
fseek(arq, 2*sizeof(atleta_t),SEEK_SET); //desloca a partir do inicio
if(fread(&buffer,sizeof(atleta_t), 1,arq) == 1) {
printf("Nome: %s\n", buffer.nome);
printf("Idade: %d\n", buffer.idade);
printf("Altura: %.2f\n\n", buffer.altura);
}
else
printf("Erro ao percorrer o arquivo.\n");
fclose(arq); // restante do código é o encerramento do programa
}
return 0;
}
//opcionalmente, poderia ler o deslocamento do teclado e armazenar em um int n:
// fseek(arq, (n-1)*sizeof(atleta_t),SEEK_SET);
// diminui 1 para corrigir o indice de deslocamento 
Funções de manipulação de posição - fseek( )
18
Exemplo: dada um arquivo binário com dados de atletas (aula anterior) imprimir na tela os dados do terceiro 
atleta cadastrado.Funções de manipulação de posição - ftell( )
19
http://en.cppreference.com/w/c/io/ftell
Funções de manipulação de posição - ftell() 
20
Exemplo: escreve e lê vetor de inteiros no arquivo binário, indicando quantos bytes foram lidos
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUMEL 5
int main( ) 
{
FILE *arq;
char nome[16];
int vetor[NUMEL];
int cont, valor;
printf("Nome do arquivo: ");
scanf("%s", nome); // n�ao aceita espa�cos
//continua...
http://en.cppreference.com/w/c/io/ftell
Funções de manipulação de posição - ftell() 
21
Exemplo: escreve e lê vetor de inteiros no arquivo binário, indicando quantos bytes foram lidos
//continuando…
// escrita do vetor
 if(!(arq = fopen(nome,"wb"))) // abre para escrita
 printf("Erro na abertura\n");
 else
 {
 printf("Entre %d valores inteiros\n", NUMEL);
 for (cont = 0; cont < NUMEL; cont++)
 {
 scanf("%d", &valor);
 fwrite(&valor,sizeof(valor), 1 ,arq);
 }
 fclose(arq); //fecha arquivo
 }
//continua...
http://en.cppreference.com/w/c/io/ftell
Funções de manipulação de posição - ftell() 
22
Exemplo: escreve e lê vetor de inteiros no arquivo binário, indicando quantos bytes foram lidos
//continuando…
// leitura do vetor
 if(!(arq = fopen(nome,"rb"))) // abre para leitura
 printf("Erro na abertura\n");
 else
 {
 for (cont = 0; cont < NUMEL; cont++) // varre o arquivo
 {
 fread(&vetor[cont],sizeof(valor), 1 ,arq);
 printf("vetor[%d] = %d\n", cont, vetor[cont]);
printf("bytes lidos = %li\n", ftell(arq)); //signed long int (li)
 }
 fclose(arq);
 }
return 0;
 }
http://en.cppreference.com/w/c/io/ftell
Lembrando do exercício da aula passada: dados de atletas.
Programa 5: Faça um programa para atualizar a idade de determinado atleta no 
arquivo binário, cujo nome foi lido via teclado.
Arquivos binários: exercício (programa 5)
#define MAX_STRLEN 31
typedef struct atleta_st
{
 char nome[MAX_STRLEN];
 int idade;
 float altura;
} atleta_t;
23
// Programa 5
int main() {
 atleta_t buffer;
 FILE *arq; //declaração do ponteiro para arquivo
 char nome[STR_MAXLEN], procurado[MAX_STRLEN];
 int encontrado, numLidos, op; //numLidos guarda quantas estruturas foram lidas de arq
 printf("Nome do arquivo (maximo %d caracteres): ", STR_MAXLEN-1);
 fgets(nome, STR_MAXLEN, stdin);
nome[ strlen(nome)-1 ] = '\0'; // remove '\n' lido
 if( !(arq = fopen(nome,"r+b")) ) // leitura e escrita (os dados permanecem)
 printf("Erro ao abrir arquivo");
 else {
// busca e atualiza
// continua...
Arquivos binários: exemplo (programa 5)
24
// continuando…
// busca e atualiza
do {
rewind(arq); // reposiciona registro corrente no início do arquivo.
printf("Nome do atleta procurado: ");
fgets(procurado, MAX_STRLEN, stdin);
encontrado = 0; //indica não encontrado (ainda)
numLidos = 0; //indica numero de estruturas lidas do arquivo
while(!feof(arq) && !encontrado) //para qdo. acha ou no fim do arquivo
if(fread(&buffer,sizeof(atleta_t),1,arq) == 1)
if( strcmp(buffer.nome, procurado) == 0) {
atualizaIdade(arq, buffer, numLidos);
encontrado = 1;
}
numLidos++;
}
printf("\n1-BuscarOutro, 2-Encerrar\n");
scanf("%i",&op);
} while(op != 2);
fclose(arq); // restante do código é o encerramento do programa
Arquivos binários: exemplo (programa 5)
25
// atualiza idade (v1): desloca a partir do inicio do arquivo numElemLidos*sizeof(atleta_t)
void atualizaIdade(FILE* arquivo, atleta_t buffer, int numElemLidos) {
printf("\nIdade cadastrada %d",buffer.idade);
printf("\nInforme alteração da idade: ");
scanf("%d",&buffer.idade);
// posiciona no lugar anterior à leitura, usando o 
// contador de elementos lidos até o momento a partir do inicio do arquivo
fseek(arq, numElemLidos*sizeof(atleta_t),SEEK_SET);
//substitui, verificando se gravação foi bem sucedida
if(fwrite(&buffer,sizeof(atleta_t),1,arq) != 1)
printf("\nErro de gravacao!!!\n");
}
Arquivos binários: exemplo (programa 5)
26
// atualiza idade (v2): desloca a partir da posicao corrente, “voltando” uma posição
void atualizaIdade(FILE* arquivo, atleta_t buffer) {
printf("\nIdade cadastrada %d",buffer.idade);
printf("\nInforme alteração da idade: ");
scanf("%d",&buffer.idade);
// posiciona no lugar anterior à leitura, usando 
// deslocamento negativo a partir da posição corrente
fseek(arq, -sizeof(atleta_t),SEEK_CUR);
//substitui, verificando se gravação foi bem sucedida
if(fwrite(&buffer,sizeof(atleta_t),1,arq) != 1)
printf("\nErro de gravacao!!!\n");
}
Arquivos binários: exemplo (programa 5)
27
Agora faça um programa que crie um arquivo de atletas de forma randômica, 
onde o código do atleta indica a posição do seu registro no arquivo. Use o 
mesmo tipo struct definido no exercício anterior.
Arquivos binários: exercício 
#define MAX_STRLEN 31
typedef struct atleta_st
{
 char nome[MAX_STRLEN];
 int idade;
 float altura;
} atleta_t;
FILE *fopen( “nome”, “modo” );
int fclose( *stream ) ; 
size_t fwrite( &buffer_letitura , element_size , quant , *stream_escrita);
size_t fread( &buffer_escrita , element_size , quant , *stream_leitura );
int fseek( *stream, offset, origin ); 
// origin : SEEK_SET SEEK_CUR SEEK_END
// modos: Cria para escrita (leitura) - w ou w+
 Abre para leitura (escrita) - r ou r+
 Atualiza arquivo, escrita (leitura) - a ou a+ 
28
Arquivos binários: exercício 
/*
Cria um arquivo com dados de uma estrutura
com informações de atletas, de forma randômica.
*/
#include <stdio.h>
#include <string.h>
#define MAXCOD 10 // codigos dos atletas entre 1 e 10
#define MAXNOME 16 // tamanho do nome do arquivo
typedef struct atleta
{
char nome[31];
int idade;
float altura;
}atleta_t;
void listaarquivo(FILE*);
29
int main ( )
{
FILE *arq;
int encontrado = 0, op, cod;
char nome[MAXNOME];
Atleta_t buffer;
printf("Nome do arquivo: ");
scanf("%s", nome); // na�o aceita espa�cos
if(!(arq = fopen(nome,"w+b"))) //cria ou recria
printf("Erro criacao");
else
{
do {
/* TRECHO DE CRIAÇÃO DO ARQUIVO NO SLIDE A SEGUIR*/
} while (op != 2);
listaarquivo(arq);
fclose(arq);
}
return 0;
}
Arquivos binários: exercício 
do { //coleta dados do usuário e os escreve
cod = le_atleta(&buffer); 
cod = cod - 1; // corrige para o índice de deslocamento no arquivo
//ajusta posicao corrente no arquivo
fseek(arq,cod*sizeof(atleta_t),SEEK_SET); 
if (fwrite(&buffer,sizeof(atleta_t),1,arq) != 1) //escreve os dados
printf(“Erro na gravacao\n”);
// força a gravação física (opcional, a gravaçao seria feita no fclose)
fflush(arq); 
printf("\n1-InserirNovo, 2-Encerrar: ");
scanf("%d", &op);
} while(op != 2);
30
Arquivos binários: exercício 
int le_atleta( atleta_t *buffer){
 //coleta dados do usuário e os escreve
 do { // lê código do atleta, com validação
 printf("Codigo do atleta, entre 1 e %d: ", MAXCOD);
 scanf("%d", &cod);
 if (cod < 1 || cod > MAXCOD)
 printf("\nCodigo deve estar entre 1 e %d:\n", MAXCOD);
 } while (cod < 1 || cod > MAXCOD);
 // fflush(stdin) 
 while((c = getchar()) != '\n' && c != EOF) ; /* limpa stdin */ 
 
 printf("Nome: ");
 fgets(buffer->nome, 30, stdin);
 printf("Idade: ");
 scanf("%d",&buffer->idade);
 printf("Altura: ");
 scanf("%f",&buffer->altura);
 return cod;
} 31
Arquivos binários: exercício 
void listaarquivo(FILE *arq)
{
atleta_t buffer;
rewind(arq); //retorna ao início, pois posição corrente pode ser outra
printf("-----Comeco da listagem-----\n");
while(!feof(arq)) { // enquanto não chegou no final
/* testa leitura, para não considerar a tentativa final, que lê EOF*/
/* Descarta registros que contém zero na idade */ 
if(fread( &buffer, sizeof(atleta_t), 1, arq) == 1 && buffer.idade != 0)
{ 
 printf("Nome: %s\n",buffer.nome);
printf("Idade: %d\n",buffer.idade);
printf("Altura: %.2f\n\n",buffer.altura);
}
}
printf("-----Fim da listagem-----\n");
}
32

Outros materiais