Buscar

Aula 23 - Arquivos binários (1) Acesso sequencial

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 55 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 55 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 55 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 (1).
Acesso sequencial
Kazuki Yokoyama
kmyokoyama@inf.ufrgs.br
Algoritmos e Programação
INF01202 – Algoritmos e Programação, 2018/01, Turmas I e J
*adaptado do material do prof. Marcelo Walter e prof. Rodrigo Ruas Oliveira e cedido pela profª. Mariana Recamonde
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
Estruturas: prototipação, declaração e
manipulação
Estruturas e funções: retorno e parâmetro por valor
Semana passada
struct nome_estrutura funcao() {
 struct nome_estrutura var;
 (...)
 return var;
}
void funcao(struct nome_estrutura par) {
 int x = par.campo1;
 par.campo2 = …;
 (...)
}
3
struct et_st {
float altura, peso;
char nome[30];
int n_olhos, n_dedos;
(...)
};
Semana passada
4
Typedef typedef struct ponto_st {
int x;
int y;
} ponto_t;
int main() {
ponto_t p1, p2, *ptr_ponto;
ptr_ponto = &p1;
(...
}
Ponteiros, estruturas e funções:
Parâmetros por referência
void le_ponto(ponto* pnt) {
 printf("\nCoordenadas do Ponto: ");
 scanf("%f %f", &pnt->x, &pnt->y);
 // ou scanf("%f %f", &(*pnt).x, &(*pnt).y);
}
void le_dados_alunos(aluno_st* alunos, int tam) {
int i, j;
for (j=0; j < tam; j++) {
 printf ( "\nALUNO %d. Nome: ",j+1);
fgets(alunos[j].nome, 15, stdin);
alunos[j].media = 0;
printf(“Digite as %d notas: ”, NRNOTAS);
 
for (i = 0; i < NRNOTAS ; i++) {
scanf(“%f”, &alunos[j].nota[i]);
while (alunos[j].nota[i] < 0 || 
alunos[j].nota[i]> 10) {
printf(“Nota invalida\n”);
scanf(“%f”, &alunos[j].nota[i]);
}
alunos[j].media += alunos[j].nota[i];
}
alunos[j].media = alunos[j].media/NRNOTAS; 
(...)
 }
} //continua…
//chamada à funcao (na main):
aluno_st listaAlunos[NALUNOS];
 le_dados_aluno(listaAlunos, NALUNOS);
Vetor de estruturas passado para 
funções por referência
Exercício
1. Defina em C um novo tipo denominado Passagem, 
conforme layout do bilhete de passagem de ônibus 
mostrado ao lado. Os campos data e horário são 
estruturas que possuem, respectivamente, 3 e 2 campos.
5
2. A partir da estrutura definida no item 1, implemente as funções ler_bilhete e mostrar_bilhete, que permitem, 
respectivamente, ler e mostrar todos os dados relativos a um determinado bilhete. A função ler_bilhete poderia 
ser implementada através de uma função sem parâmetros que retorna um struct, ou através de uma função void 
(ou seja, sem retorno) que recebe o struct como parâmetro por referência. Tente implementar e testar os dois 
casos para praticar!
3. Na main(), declare um vetor de estruturas tipo Passagem, que irá armazenar todos os Bilhetes vendidos em um 
determinado período pela Viação Viaje Bem (assuma um máximo de 200 bilhetes). Leia e posteriormente imprima 
as informações de N passagens usando as funções declaradas, onde N será informado pelo usuário e deve ser 
validado (N < 200).
4. Por fim, faça uma função que receba o vetor de estruturas tipo Passagem, o número de passagens vendidas 
(N) e imprima na tela os dados de todas as passagens vendidas em um determinado mês, também informado 
como parâmetro da função (por exemplo, “Janeiro”, ‘J’ ou 0). Teste a chamada desta função na main().
Exercício
1. Defina em C um novo tipo denominado Passagem, 
conforme layout do bilhete de passagem de ônibus 
mostrado ao lado. Os campos data e horário são 
estruturas que possuem, respectivamente, 3 e 2 campos.
6
// Definicoes necessarias
#include <stdio.h>
#include <string.h>
#define MAX 31
typedef struct data
{
 int dia, mes, ano;
} Data_st;
typedef struct horario
{
 int hora, min;
} Horario_st;
typedef struct passagem
{
 int cod;
 char nome[MAX], destino[MAX], origem[MAX];
 Data_st data;
 Horario_st horario;
 int assento;
 float valor;
} Passagem_st;
//continua...
2. A partir da estrutura definida no item 1, implemente as funções ler_bilhete e mostrar_bilhete, que permitem, 
respectivamente, ler e mostrar todos os dados relativos a um determinado bilhete. A função ler_bilhete poderia 
ser implementada através de uma função sem parâmetros que retorna um struct, ou através de uma função 
void (ou seja, sem retorno) que recebe o struct como parâmetro por referência. Tente implementar e testar os 
dois casos para praticar!
7
void ler_bilhete (Passagem_st* bilhete) {
 printf("Codigo: ");
 scanf("%d", &bilhete->cod);
 printf("Data (dia mes ano): ");
 scanf("%d %d %d", &bilhete->data.dia,&bilhete->data.mes,&bilhete->data.ano);
 printf("Horario (hora minutos): ");
 scanf("%d %d", &bilhete->horario.hora,&bilhete->horario.min);
 printf("Nome do passageiro: ");
 fflush(stdin);
 fgets(bilhete->nome,MAX-1,stdin);
 printf("Origem: ");
 fflush(stdin);
 fgets(bilhete->origem,MAX-1,stdin);
 printf("Destino: ");
 fflush(stdin);
 fgets(bilhete->destino,MAX-1,stdin);
 printf("Assento: ");
 scanf("%d", &bilhete->assento); 
 printf("Valor: ");
 scanf("%f", &bilhete->valor); 
}
//continua...
2. A partir da estrutura definida no item 1, implemente as funções ler_bilhete e mostrar_bilhete, que permitem, 
respectivamente, ler e mostrar todos os dados relativos a um determinado bilhete. A função ler_bilhete poderia 
ser implementada através de uma função sem parâmetros que retorna um struct, ou através de uma função 
void (ou seja, sem retorno) que recebe o struct como parâmetro por referência. Tente implementar e testar os 
dois casos para praticar!
8
void mostrar_bilhete (Passagem_st bilhete) {
 
 printf("Codigo: %d\n", bilhete.cod);
 printf("Data: %2d/%2d/%4d\n",bilhete.data.dia,bilhete.data.mes,bilhete.data.ano);
 printf("Horario: %2d:%2d\n",bilhete.horario.hora,bilhete.horario.min);
 printf("Nome Passageiro: %s\n", bilhete.nome);
 printf("Origem: %s\n", bilhete.origem);
 printf("Destino: %s\n", bilhete.destino);
 printf("Valor: R$ %.2f\n", bilhete.valor);
}
//continua...
3. Na main(), declare um vetor de estruturas tipo Passagem, que irá armazenar todos os Bilhetes vendidos em 
um determinado período pela Viação Viaje Bem (assuma um máximo de 200 bilhetes). Leia e posteriormente 
imprima as informações de N passagens usando as funções declaradas, onde N será informado pelo usuário e 
deve ser validado (N < 200).
9
int main() {
 Passagem_st novobilhete[200];
 int i,n;
 do{
printf("Numero de passagens a processar? ");
 scanf("%d",&n);
if (n < 0 || n > 200)
printf(“Valor invalido!\n”);
 } while(n < 0 || n > 200);
 
 for(i=0; i<n ; i++)
 ler_bilhete(&novobilhete[i]);
 
 for(i=0; i<n ; i++)
 mostrar_bilhete(novobilhete[i]);
 
 
 return 0;
}
4. Por fim, faça uma função que receba o vetor de estruturas tipo Passagem, o número de passagens vendidas 
(N) e imprima na tela os dados de todas as passagens vendidas em um determinado mês, também informado 
como parâmetro da função (por exemplo, “Janeiro”, ‘J’ ou 0). Teste a chamada desta função na main().
10
void vendas_no_mes(Passagem_st* bilhetes, int tam, int mes)
{
 int i, cont=0;
 printf("Vendas no mes: %d\n",mes);
 for (i=0; i< tam; i++){
 if (bilhetes[i].data.mes == mes) {
 cont++;
 printf("---Registro encontrado---\n");
 printf("Codigo: %d\n", bilhetes[i].cod);
 printf("Data: %2d/%2d/%4d\n",bilhetes[i].data.dia,bilhetes[i].data.mes,bilhetes[i].data.ano);
 printf("Horario: %2d:%2d\n",bilhetes[i].horario.hora,bilhetes[i].horario.min);
 printf("Nome Passageiro: %s\n", bilhetes[i].nome);
 printf("Origem: %s\n", bilhetes[i].origem);
 printf("Destino: %s\n", bilhetes[i].destino);
 printf("Valor: R$ %.2f\n\n", bilhetes[i].valor);
 
 }
 }
 if (cont==0)
 printf("Nenhum registro encontrado!\n");
}
4. Por fim, faça uma função que receba o vetor de estruturas tipo Passagem, o número de passagens vendidas 
(N) e imprima na tela os dados de todas as passagens vendidas em um determinado mês, também informado 
como parâmetro da função (por exemplo, “Janeiro”, ‘J’ ou 0).Teste a chamada desta função na main().
11
int main() {
 Passagem_st novobilhete[200];
 int i,n;
 do{
printf("Numero de passagens a processar? ");
 scanf("%d",&n);
if (n < 0 || n > 200)
printf(“Valor invalido!\n”);
 } while(n < 0 || n > 200);
 
 for(i=0; i<n ; i++)
 ler_bilhete(&novobilhete[i]);
 
 for(i=0; i<n ; i++)
 mostrar_bilhete(novobilhete[i]);
 
 vendas_no_mes(novobilhete, n, 03);
 return 0;
}
Arquivos Binários (1),
acesso sequencial
12
Repositórios permanentes de dados (informações) que 
possibilitam a comunicação dos programas com o 
ambiente.
Usualmente armazenados em dispositivos de memória 
auxiliar (discos).
A alteração de um arquivo durante a execução de um 
programa possibilita salvar o processamento realizado, 
tornando-o permanente (além do tempo de execução do 
programa).
Em arquivos é possível armazenar bem mais informações 
do que na memória principal.
Arquivos
13
int bufferInt[10];
char bufferchar[10];
Stream (fluxo): repositórios permanentes de sequências 
de bytes armazenados em dispositivos de memória 
permanente, a partir do uso de periféricos (discos, pen 
drives, etc.) que aceitam tanto a leitura como a gravação 
de dados.
Device independent: toda a entrada ou saída de dados é 
processada da mesma forma, através do processamento 
de streams, independentemente do periférico utilizado 
(discos, pen drives, mouse, teclado, tela etc)
Buffers: As operações de entrada e saída de dados de um 
arquivo (incluídos os dispositivos padrão stdin/stdout) são 
apoiadas pelo armazenamento temporário destes streams 
em áreas da memória principal denominadas buffers.
Arquivos em C
14
Arquivos: esquema de manipulação
Arquivo: entidade externa ao programa
Armazenamento permanente ( não se perdem ao término do 
programa) das informações em memória secundária (periférica)
15
Binário: composto por uma sequência (fluxo binário) de 
bytes lidos/escritos, sem tradução, diretamente do/no 
dispositivo externo. Existe uma correspondência um para 
um entre os dados do dispositivo e os do fluxo. 
Texto: composto de uma sequência de bytes 
correspondendo a uma sequência de caracteres ASCII 
(letras, dígitos e caracteres especiais) utilizados na escrita 
e separadores (espaço em branco, tab, nova linha..). 
Dependendo do sistema utilizado (Windows, Linux, ou 
Mac), a terminação de linha difere:
Windows: \r\n;
Unix (Linux, BSD, Mac OSX): \n;
Mac classic: \r;
Tipos de arquivos em C
Aula de hoje
16
Arquivos binários
Fisicamente: sequência de bits (0's e 1's), armazenada de forma 
sequencial na unidade de bytes (8 bits). O tamanho é teoricamente 
ilimitado.
17
Logicamente: o stream pode ser visto como um conjunto de dados simples, ou 
estruturado, cuja organização depende do programa que utiliza o arquivo.
Unidade de manipulação: somente um elemento pode ser acessado de cada vez, em 
uma posição corrente na stream. O tamanho do elemento corrente depende para cada 
dispositivo (geralmente 1 byte). Os elementos correntes não têm nome.
Acesso aos dados - Sequencial vs. Aleatório: sequencial lê os dados na ordem do 
stream, enquanto o aleatório seleciona uma posição em qualquer ponto do stream.
C: stream vs. arquivo
Stream:
Conjunto sequencial de bytes, sem qualquer estrutura interna
São vistos por programas ou comandos como fluxo de bytes
Arquivo:
Característica física: 
stream (fluxo de bytes)
Característica lógica:
Na memória principal, o buffer pode ser visualizado e manipulado pelo 
programa como valores simples ou estruturados
18
Arquivos binários: armazenamento
19
No contexto da disciplina, 
trataremos de arquivos binários 
que armazenam informações de 
somente um tipo de dado, seja ele 
simples (int, char, float) ou 
estruturado (arranjos ou estruturas)
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); 20
Arquivos binários: FILE (declaração)
Sintaxe e exemplo:
FILE *nome_arquivo;
Definição: estrutura que armazena informações de manipulação de arquivos 
(qual o arquivo, onde ele está, qual a posição atual no arquivo, tamanho, …)
Para que um arquivo possa ser usado pelo programa, é necessário que seja 
declarado através da estrutura FILE, onde cada arquivo a ser usado pelo 
programa é associado a uma variável do tipo apontador
#include <stdio.h>
(...)
int main() {
FILE *arquivo;
FILE *times, *pontuacao;
(...)
}
Observar que FILE é 
sempre escrito em 
maiúsculas!
Para cada arquivo a ser usado 
simultaneamente no programa, 
deve haver um ponteiro 21
Arquivos binários: abertura
Sintaxe:
FILE *nome_var; //declaração
 nome_var = fopen("nome do arquivo","modo de abertura");
Abre/cria/recria um arquivo para permitir sua manipulação
Parâmetros: string nome do arquivo físico (completo ou relativo)
 string modo de abertura desejado
Retorno: ponteiro do tipo FILE com endereço inicial para a estrutura de 
 manipulação deste arquivo 
 OU
 NULL, se a função não tiver sido bem sucedida
Após abertura, verificar SEMPRE se não houve erro!
22
Arquivos binários: modos de abertura
Sintaxe:
 nome_var = fopen("nome do arquivo","modo de abertura");
O modo de abertura define o tipo de acesso que o programa terá sobre o 
arquivo
23
Arquivos binários: abertura - Exemplo
#include <stdio.h> // inclui as funções com arquivos
int main( )
{
 FILE *arq1, *arq2; // declaração de apontadores de arquivo
 arq1 = fopen("c:\\exemplo1.bin","rb"); // abertura para leitura (caminho completo)
 if (arq1 == NULL) { // verifica se funcionou: retorno NULL indica erro
 printf("Erro na abertura do arquivo 1.");
 }
 else {
 // abertura para leitura, junto à análise do resultado da operação:
 if (!(arq2 = fopen("c:\\exemplo2.dat","rb")) { // not(null) = true
 printf("Erro na abertura do arquivo 2.");
 }
 ...
 }
 ...
24
Arquivos binários: abertura - Exemplo
#include <stdio.h> // inclui as funções com arquivos
int main( )
{
 FILE *arq1, *arq2; // declaração de apontadores de arquivo
 arq1 = fopen("c:\\exemplo1.bin","rb"); // abertura para leitura (caminho completo)
 if (arq1 == NULL) { // verifica se funcionou: retorno NULL indica erro
 printf("Erro na abertura do arquivo 1.");
 }
 else {
 // abertura para leitura, junto à análise do resultado da operação:
 if (!(arq2 = fopen("c:\\exemplo2.dat","rb")) { // not(null) = true
 printf("Erro na abertura do arquivo 2.");
 }
 ...
 }
 ...
25
Duas maneiras de testar se a 
abertura do arquivo ocorreu 
corretamente!
Arquivos binários: fechamento
Sintaxe:
FILE *nome_var; //declaração
 nome_var = fopen("nome do arquivo","modo de abertura");
(...)
fclose(nome_var); //ponteiro do tipo FILE passado como argumento
Fecha um arquivo para garantir que dados escritos estão consistentes e liberar 
sua manipulação por outro programa
Parâmetros: ponteiro do tipo FILE com endereço inicial para a
 estrutura de manipulação deste arquivo
Sem retorno.
Pode apresentar erro, caso o ponteiro passado seja inválido!
26
Arquivos binários: fechamento - Exemplo
27
#include <stdio.h> // inclui as funções com arquivos
int main( )
{
 FILE arq1; // declaração de apontadores de arquivo
 arq1 = fopen("exemplo.bin","rb"); // abertura para leitura (caminho relativo)
 if (!arq1) { // verifica se funcionou:not(null) = true
 printf("Errona abertura do arquivo exemplo.bin.");
 }
 else {
 // efetua operacoes no arquivo com funcoes de manopulacao 
 …
 fclose(arq1); // fecha arquivo apos o uso
 }
 return 0;
}
 
É dever do programador lembrar de fechar 
corretamente o arquivo para garantir 
consistência dos dados
Utilizando arquivos em C: funções de manipulação
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 pointeiro 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); 28
Arquivos binários: acesso sequencial
Funções de manipulação de arquivos binários
29
Funções de manipulação: fread()
30
Funções de manipulação: fwrite()
31
Funções de manipulação: feof()
32
Ler uma quantidade determinada de números inteiros, e gravar em um arquivo 
binário. Depois, ler os valores do arquivo e armazenar em um vetor.
Exemplo
33
Dica: sizeof( var ) ou sizeof( TIPO ) retorna o tamanho, em bytes, de uma 
variável ou tipo.
Exemplos:
int numero;
char letra;
sizeof( numero ); // retorna 4 (4 bytes)
sizeof( int ); // retorna 4 (4 bytes)
sizeof( letra ); // retorna 1 (1 byte)
sizeof( char ); // retorna 1 (1 byte)
// Programa de manipulação de arquivos: escrita e leitura
#include <stdio.h>
#include <string.h>
#define NUMEL 5
int main( ) {
FILE *arq; //declaração de um ponteiro para arquivo
char nome[16];
int vetor[NUMEL], cont, valor;
printf("Digite o nome do arquivo: ");
scanf("%s", nome); // ATENÇÃO: não aceita espaços
// escrita do vetor
// continua...
34
Exemplo
// continuando...
// escrita: le dados do teclado, elemento a elemento, e vai copiando ao arquivo
if(!(arq = fopen(nome,"wb"))) // abre para escrita e testa a abertura
printf("Erro na abertura\n");
else {
printf("Entre %d valores inteiros\n", NUMEL);
for (cont = 0; cont < NUMEL; cont++){
scanf("%d", &valor);
// escreve 1 quant de 4 bytes (sizeof valor) e testa escrita
if (fwrite(&valor, sizeof(valor), 1, arq) != 1)
printf("Erro na escrita!\n");
}
fclose(arq); // fecha o arquivo
}
// leitura do vetor, elemento a elemento
// continua...
35
Exemplo
// continuando...
// leitura: le dados do arquivo, elemento a elemento, e vai armazenando no vetor
if(!(arq = fopen(nome,"rb"))) // abre para leitura
printf("Erro na abertura\n");
else {
for (cont = 0; cont < NUMEL; cont++) { // varre o arquivo
// le 1 quant de 4 bytes (sizeof valor) do arquivo e testa leitura
if (fread(&vetor[cont], sizeof(valor), 1, arq) == 1)
printf("vetor[%d] = %d\n", cont, vetor[cont]);
else
printf("Erro na leitura!!\n");
}
fclose(arq); // fecha o arquivo
}
return 0;
}
36
Exemplo
// continuando...
// leitura v2: le os dados de uma só vez e copia ao vetor
if(!(arq = fopen(nome,"rb"))) // abre para leitura
printf("Erro na abertura\n");
else {
quant_lida = fread(vetor, sizeof(valor), NUMEL, arq);
fclose(arq);
}
if (quant_lida != NUMEL) // teste da leitura
 printf("Erro na leitura\n");
else
 for (cont = 0; cont < NUMEL; cont++)
 printf("vetor[%d] = %d\n", cont, vetor[cont]);
return 0;
}
37
Exemplo
Indica leitura de informações com o 
tamanho em bytes de valor multiplicado 
por NUMEL vezes
Funções de manipulação: fflush()
38
Funções de manipulação: rewind()
39
Faça 4 programas diferentes para manipular dados de atletas.
1. Gravar um arquivo composto por estruturas que contenham o seguinte 
conjunto de dados: nome (até 30 letras), idade e altura.
2. Listar um arquivo com estas estruturas.
3. Exibir a altura de um determinado atleta, cujo nome foi lido do teclado.
4. Adicionar um novo registro no final do arquivo.
Arquivos binários: exercício
40
// Programa de manipulação de arquivos
// Definicoes necessarias
#include <stdio.h>
#include <string.h>
#define MAX_STRLEN 31
typedef struct atleta_st
{
 char nome[MAX_STRLEN];
 int idade;
 float altura;
} atleta_t;
Arquivos binários: exercício
41
// Programa 1
int main() {
 atleta_t buffer; 
 FILE *arq; //declaração do ponteiro para arquivo
 char nome[STR_MAXLEN];
 int op;
 printf("Nome do arquivo (maximo %d caracteres): ", STR_MAXLEN-1);
 fgets(nome, STR_MAXLEN, stdin);
nome[ strlen(nome)-1 ] = '\0' // remove '\n' lido pelo fgets
 if( !(arq = fopen(nome,"wb")) ) //cria (ou grava por cima), validando
 printf("Erro criacao");
 else {
// coleta dados do usuário e grava no arquivo
// continua...
Arquivos binários: exercício (programa 1)
42
// continuando...
// coleta dados do usuário e grava no arquivo
do {
printf("\nNome (ate' %d letras): ", MAX_STRLEN-1);
fgets(buffer.nome, MAX_STRLEN, stdin);
printf("\nIdade: ");
scanf("%d",&buffer.idade);
printf("\nAltura: ");
scanf("%f",&buffer.altura);
if (fwrite(&buffer, sizeof(atleta_t), 1, arq) != 1)
printf("Erro de escrita\n");
printf("\n1-InserirNovo, 2-Encerrar\n");
scanf("%i",&op);
} while(op != 2);
fclose(arq); //fecha
} // else
return 0; // Fim do programa 1
}
Arquivos binários: exercício (programa 1)
43
// continuando...
// coleta dados do usuário e grava no arquivo
do {
printf("\nNome (ate' %d letras): ", MAX_STRLEN-1);
fgets(buffer.nome, MAX_STRLEN, stdin);
printf("\nIdade: ");
scanf("%d",&buffer.idade);
printf("\nAltura: ");
scanf("%f",&buffer.altura);
if (fwrite(&buffer, sizeof(atleta_t), 1, arq) != 1)
printf("Erro de escrita\n");
printf("\n1-InserirNovo, 2-Encerrar\n");
scanf("%i",&op);
} while(op != 2);
fclose(arq); //fecha
} // else
return 0; // Fim do programa 1
}
Arquivos binários: exercício (programa 1)
44
// Programa 2
int main() {
 atleta_t buffer;
 FILE *arq; //declaração de 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 pelo fgets
 if( !(arq = fopen(nome,"rb")) ) // abre para leitura, posiciona no início
 printf("Erro na abertura\n");
 else {
// listagem sequencial
// continua...
Arquivos binários: exercício (programa 2)
45
Arquivos binários: exercício (programa 2)
// continuando...
// listagem sequencial
printf("-----Comeco da listagem-----\n");
while(!feof(arq)) { // enquanto não chegou no final
// testa leitura, para não considerar a tentativa no final
 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);
}
}
printf("-----Fim da listagem-----\n");
fclose(arq);
} // else
return 0; // Fim do programa 2
}
46
Arquivos binários: exercício (programa 2)
// continuando...
// listagem sequencial
printf("-----Comeco da listagem-----\n");
while(!feof(arq)) { // enquanto não chegou no final
// testa leitura, para não considerar a tentativa no final
 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);
}
}
printf("-----Fim da listagem-----\n");
fclose(arq);
} // else
return 0; // Fim do programa 2
}
47
// Programa 3
int main() {
 atleta_t buffer;
 char nome[MAX_STRLEN];
 FILE *arq; //declaração de ponteiro para arquivo
 int encontrado, op;
 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,"rb"))) //leitura, validando
 printf("Erro abertura");
else {
// busca
// continua...
Arquivos binários: exercício (programa 3)
48
// continuando... busca
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);
fclose(arq);
} // else
return 0; // Fim do programa 3
}
Arquivos binários: exercício (programa 3)
49
// continuando... busca
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);
fclose(arq);
} // else
return 0; // Fim do programa 3
}
Arquivos binários: exercício (programa 3)
50
// Programa 4
int main() {
 atleta_t buffer;
FILE *arq;
char nome[MAX_STRLEN];
int op;
 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,"ab"))) // abre em "modo append" (acrescentar dados)
printf("Erro na abertura para acrescentar");
else {
// adiciona dados
// continua...
Arquivos binários: exercício (programa 4)
51
// continuando...
// adiciona dados
do { // gravados a partir do final do arquivo:
printf("\nNome (ate' %d letras): ", MAX_STRLEN-1);
fgets(buffer.nome, MAX_STRLEN, stdin);
printf("\nIdade: ");
scanf("%d",&buffer.idade);
printf("\nAltura: ");
scanf("%f",&buffer.altura);
if (fwrite(&buffer,sizeof(TIPO_ATLETA),1,arq) != 1)
printf("Erro na escrita\n");
printf("\n1-Inserir novo, 2-Encerrar\n");
scanf("%d", &op);
} while(op != 2);
fclose(arq);
} // else
return 0; // Fim do programa 4
}
Arquivos binários: exercício (programa 4)
52
Outras funções de manipulação: ferror()
53
Outras funções de manipulação: rename(), remove()
54
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 arq uivo, 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:
55

Outros materiais