MANIPULAÇÃO DE DADOS EM ARQUIVO BINÁRIO
Caso seja necessário criar um programa que grave, altere ou exclua dados dos frequentadores de uma academia, nesse tutorial vamos ver passo a passo como criar um código eficiente para isso, desde a criação de uma struct, até a exclusão de um frequentador por completo.
Criando e inserindo dados de uma struct em um arquivo:
A primeira coisa a fazer é entender o problema, neste tutorial vamos usar como referência os dados dos frequentadores de uma academia, que são: cpf, nome, peso, sexo e data de inscrição, depois disso, crie uma struct, veja um exemplo:
#include<stdio.h> #include <conio.h> #define MAX_CPF 12 #define MAX_NOME 60 // Inicio da criação da Estrutura: typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; // data de inscrição. }tipoFrequentador; // Criando um tipo de dado da estrutura:
Note que depois da criação da struct é criado um tipo de dado dela, esse tipo será bastante usado na manipulação de dados em arquivo, por isso é sempre importante criar um para cada struct que você declarar.
Agora que você tem o tipo da estrutura criado, é possivel declarar uma variável usando o novo tipo, exemplo:
//... // Declaracoes tipoFrequentador cliente; //...
O próximo passo será efetuar a leitura dos dados, exemplo: (Como é um exemplo nenhuma leitura está sendo validada, porém não se esqueça de validar todos os dados!) :
//... int main(void) { // Declaracoes tipoFrequentador cliente; // Instrucoes puts("Digite o CPF do frequentador:"); scanf("%s",cliente.cpf); // Lendo o CPF puts("Digite o Nome do frequentador:"); scanf("%s",cliente.nome); // Lendo o Nome completo fflush(stdin); puts("Digite o Peso do frequentador:"); scanf("%f",&cliente.peso); // Lendo o Peso fflush(stdin); puts("Digite o Sexo do frequentador:"); scanf("%c",&cliente.sexo); // Lendo o Sexo (M ou F) puts("Digite o Dia de inscricao do frequentador:"); scanf("%d",&cliente.dia); // Lendo o dia puts("Digite o Mes de inscricao do frequentador:"); scanf("%d",&cliente.mes); // Lendo o mês puts("Digite o Ano de inscricao do frequentador:"); scanf("%d",&cliente.ano); // Lendo o ano getch(); return 0; } //...
Criando um arquivo:
Após a leitura dos dados, já é possível gravar essa struct em arquivo, mas primeiro é preciso criar esse arquivo! O primeiro passo é declarar um arquivo, para isso há até um tipo específico que é o "FILE", veja o exemplo:
//... // Declaracoes FILE *arqFrequentadores; //Declaração de um arquivo tipoFrequentador cliente //...
Note que a variável é na verdade um ponteiro, só que do tipo FILE, ou seja, ela vai armazenar o endereço de seu arquivo. Observe que seu arquivo ainda não foi criado, apenas a variável que vai armazenar o endereço dele é que foi decladara!
Para seu arquivo passar a existir, você precisa abrí-lo, mas antes você precisa pensar em um nome para ele, como neste caso estamos usando uma estrutura para frequentadores de uma academia, um nome ideal seria "dadosFrequentadores.bin", note que a extensão não será necessariamente ".bin", podendo ficar à escolha do programador! Após pensar no nome de seu arquivo, crie um "define" com o nome nome dele:
//... #define ARQFREQUENT "dadosFrequentadores.bin" //...
Isso vai facilitar bastante o trabalho do programador, pois caso ele queira mudar a extensão ou o nome do arquivo, tudo será feito em apenas uma linha. No exemplo acima está sendo usado "ARQFREQUENT", mas não hesite em usar outros nomes que você não esqueça! (tudo em maiúsculo!).
Agora que você sabe o nome do arquivo, já é possivel abrí-lo, sempre é aconselhável abrir os arquivos apenas quando necessário, e feito isso, fechá-lo imediatamente! Ou seja, vamos abrí-lo apenas na hora de gravar os dados nele! O próximo passo é criar uma função que grave os dados dessa struct no arquivo, essa função vai receber como parâmetro o endereço de sua struct. Veja o exemplo:
//... // Subprograma 1 // Objetivo : Gravar uma estrutura de dados em um arquivo bínario. // Parâmetro : Struct. // Retorno : Nenhum. void gravaDados(tipoFrequentador *estrutura) // O parâmetro é um ponteiro que vai receber o endereço da estrutura! { FILE *arq; // Declarando um ponteiro de arquivo. if (!(arq = fopen(ARQFREQUENT,"a+b"))) // Abrindo o arquivo(caso não tenha sucesso, será executado o "exit(1)" exit(1); fwrite(estrutura,sizeof(tipoFrequentador),1,arq); // Gravando a estrutura completa no arquivo! fclose(arq); // fechando o arquivo imediatamente. } //... Não se esqueça de criar o protótipo da função!
No exemplo acima, como usamos o modo "a+b" de abertura, se o arquivo não existir ele será criado, e se existir será atualizado (será aberto com o apontador no final do arquivo), para arquivos não-binários use "a+t". Para chamar essa função que acabamos de criar, mande como parâmetro o endereço da struct que você acabou de ler, exemplo:
//... gravaDados(&cliente); //...
Feito isso, você terminou a gravação dos dados, você vai encontrar esse arquivo na mesma pasta em que seu código fonte está salvo! Você pode até abrí-lo com o bloco de notas, mas como a gravação foi binária você não vai entender o que foi escrito, apenas o computador! Veja o código fonte do exemplo completo:
/* Sintese Objetivo: Salvar uma estrutura de dados em um arquivo binário. Entrada : Cpf,nome,peso,sexo,data de inscrição. Saida : Nenhuma. */ #include<stdio.h> #include <conio.h> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" // Estruturas typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; } tipoFrequentador; // Protótipos void gravaDados(tipoFrequentador *estrutura); // Instruções int main(void) { // Declaracoes tipoFrequentador cliente; FILE *arqFrequentadores; // Instrucoes // PRIMEIRO EFETUANDO A LEITURA DOS DADOS puts("Digite o CPF do frequentador:"); scanf("%s",cliente.cpf); puts("Digite o Nome do frequentador:"); scanf("%s",cliente.nome); fflush(stdin); puts("Digite o Peso do frequentador:"); scanf("%f",&cliente.peso); fflush(stdin); puts("Digite o Sexo do frequentador:"); scanf("%c",&cliente.sexo); puts("Digite o Dia de inscricao do frequentador:"); scanf("%d",&cliente.dia); puts("Digite o Mes de inscricao do frequentador:"); scanf("%d",&cliente.mes); puts("Digite o Ano de inscricao do frequentador:"); scanf("%d",&cliente.ano); // FIM DA LEITURA gravaDados(&cliente); system("CLS"); printf("Dados gravados!\n"); getch(); return 0; } // Subprograma 1 // Objetivo : Gravar uma estrutura de dados em um arquivo bínario. // Parâmetro : Struct. // Retorno : Nenhum. void gravaDados(tipoFrequentador *estrutura) { FILE *arq; if (!(arq = fopen(ARQFREQUENT,"a+b"))) exit(1); fwrite(estrutura,sizeof(tipoFrequentador),1,arq); fclose(arq); }
Observações importantes: O programa acima é apenas um exemplo, ele salva somente uma struct por vez! Para fazer um programa que leia diversos registros de clientes e os salve, você terá que mudar a lógica, de forma que após a gravação, seja permitido a gravação de mais clientes, lembre-se: não é necessária a criação de um vetor de struct, pois o próprio arquivo é um vetor. Use a mesma struct para ler os dados de todos os frequentadores!
Alterando dados em um arquivo
Para alterar dados em um arquivo, é preciso seguir alguns passos para o sucesso da operação, neste exemplo você vai alterar os dados de um frequentador da academia, de acordo com os seguintes passos:
-Pedir o CPF do frequentador a ser alterado.
-Localizar a struct com esse CPF.
-Pedir o que ele deseja alterar (o CPF não pode ser alterado).
-Ler o novo dado que o usuário informar.
-Chamar uma das funções de alteração de acordo com a escolha do usuário.
-Confirmar a alteração.
-Gravar o novo dado por cima do antigo.
-Fim.
Para a realização da alteração de dados em arquivo, é necessário ter um bom conhecimento da função fseek em conjunto com sizeof.
Veja um exemplo de como localizar uma struct no arquivo com o CPF que o usuário digitou:
#include<stdio.h> #include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" //Estruturas: typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; } tipoFrequentador ; //Protótipos: int localizaStructPorCpf(char *pCpfDigitado); int main(void) { // Declaracoes int posicaoStruct; char cpfDigitado[MAX_CPF]; // Instrucoes printf("Digite o cpf do frequentador que deseja alterar:\n"); scanf("%s",cpfDigitado); //Validar CPF! posicaoStruct = localizaStructPorCpf(cpfDigitado); if (posicaoStruct == -1) printf("Nenhum Registro com esse CPF foi encontrado!\n"); else { //Se entrar aqui, é porque achou o CPF! //Próximo passo: chamar as funções de alteração. } getch(); return 0; } // Subprograma 1 // Objetivo : Encontrar uma Struct com o mesmo CPF digitado. // Parâmetro : Cpf Digitado. // Retorno : Posição da estrutura no arquivo. int localizaStructPorCpf(char *pCpfDigitado) { FILE *arq; int contBytes=0; tipoFrequentador estrutura; if (!(arq = fopen(ARQFREQUENT,"rb"))) // Abrindo com o modo 'apenas leitura'. exit(1); while(fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { contBytes=ftell(arq); if (strcmp(estrutura.cpf,pCpfDigitado)==0) { fclose(arq); // sempre fechar arquivo return contBytes - sizeof(tipoFrequentador); } } // se saiu o while, quer dizer que não achou nenhum cpf equivalente! fclose(arq); //sempre fechar arquivo return -1; }
Caso o usuário digite um CPF válido, a nova função retorna a posição do registro deste frequentador, caso contrário ela retorna -1, indicando que não existe frequentador com tal CPF. Agora que já temos o frequentador desejado, peça ao usuário qual dos dados ele deseja alterar, veja um exemplo:
#include <stdio.h>#include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; }tipoFrequentador; int main(void) { // Declaracoes int opcao; tipoFrequentador novaEstrutura; // Instrucoes do { printf("Digite o que você deseja alterar:\n\n"); printf("1 - Nome\n"); printf("2 - Peso\n"); printf("3 - Sexo\n"); printf("4 - Data de inscricao\n\n"); scanf("%d",&opcao); if ((opcao < 1) || (opcao > 4)) printf("opcao invalida! Digite novamente:\n"); }while((opcao < 1) || (opcao > 4)); switch(opcao) { case 1: { printf("\nDigite o novo nome:\n"); scanf("%s",novaEstrutura.nome); //Validar nome. //Perguntar ao usuario se deseja mesmo alterar... //Chamar a função de alterar nome. break; } case 2: { printf("\nDigite o novo peso:\n"); scanf("%f",novaEstrutura.peso); //Validar peso. //Perguntar ao usuario se deseja mesmo peso... //Chamar a função de alterar peso. break; } case 3: { printf("\nDigite o novo sexo:\n"); scanf("%c",novaEstrutura.sexo); //Validar sexo. //Perguntar ao usuario se deseja mesmo sexo... //Chamar a função de alterar sexo. break; } case 4: { puts("Digite o novo dia:"); scanf("%d",&novaEstrutura.dia); puts("Digite o novo mes:"); scanf("%d",&novaEstrutura.mes); puts("Digite o novo ano:"); scanf("%d",&novaEstrutura.ano); //Validar data //Perguntar ao usuario se deseja mesmo alterar data... //Chamar a função de alterar data. } } getch(); return 0; }
Agora que você já tem a posição do frequentador e o novo dado, é possivel ir para o último passo, a alteração de dados, que consiste basicamente em escrever a nova informação por cima da antiga. Neste exemplo, você vai criar uma função que altere o nome de um frequentador: Primeiramente observe o corpo da função de alterar nome:
// Subprograma 1 // Objetivo : Alterar o nome de um frequentador. // Parâmetro : Posição da struct e novo nome // Retorno : Nenhum. void alteraNomeFrequentador(int posicao, char *pNovoNome) { FILE *arq; if (!(arq = fopen(ARQFREQUENT,"r+b"))) // Abrindo com o modo 'Leitura e escrita'. exit(1);//erro ao abrir o arquivo. fseek(arq,posicao,1); //Neste fseek estamos movendo o apontador do arquivo para a estrutura a ser alterada fseek(arq,MAX_CPF,1); //já neste estamos movendo o apontador para o inicio do nome do frequentador //e como só o CPF vem antes do nome, temos que saltar o tamanho do CPF. fwrite(pNovoNome,MAX_NOME,1,arq); fclose(arq); printf("Nome modificado com sucesso!\n"); }
Agora observe o uso prático dela:
#include<stdio.h> #include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; } tipoFrequentador; //Protótipos: int localizaStructPorCpf(char *pCpfDigitado); void alteraNomeFrequentador(int posicao, char *pNovoNome); int main(void) { // Declaracoes int opcao; int posicaoStruct; char cpfDigitado[MAX_CPF]; tipoFrequentador novaEstrutura; // Instrucoes printf("Digite o cpf do frequentador que deseja alterar:\n"); scanf("%s",cpfDigitado); //Validar CPF! posicaoStruct = localizaStructPorCpf(cpfDigitado); if (posicaoStruct == -1) printf("Nenhum Registro com esse CPF foi encontrado!\n"); else { do { printf("Digite o que você deseja alterar:\n\n"); printf("1 - Nome\n"); printf("2 - Peso\n"); printf("3 - Sexo\n"); printf("4 - Data de inscricao\n\n"); scanf("%d",&opcao); if ((opcao < 1) || (opcao > 4)) printf("opcao invalida! Digite novamente:\n"); }while((opcao < 1) || (opcao > 4)); switch(opcao) { case 1: { printf("\nDigite o novo nome:\n"); scanf("%s",novaEstrutura.nome); //Validar nome. //Perguntar ao usuario se deseja mesmo alterar... alteraNomeFrequentador(posicaoStruct,novaEstrutura.nome); break; } case 2: { printf("\nDigite o novo peso:\n"); scanf("%f",&novaEstrutura.peso); //Validar peso. //Perguntar ao usuario se deseja mesmo alterar... //Chamar a função de alterar peso. break; } case 3: { printf("\nDigite o novo sexo:\n"); scanf("%c",&novaEstrutura.sexo); //Validar sexo. //Perguntar ao usuario se deseja mesmo sexo... //Chamar a função de alterar sexo. break; } case 4: { puts("Digite o novo dia:"); scanf("%d",&novaEstrutura.dia); puts("Digite o novo mes:"); scanf("%d",&novaEstrutura.mes); puts("Digite o novo ano:"); scanf("%d",&novaEstrutura.ano); //Validar data //Perguntar ao usuario se deseja mesmo alterar data... //Chamar a função de alterar data. } } } getch(); return 0; } // Subprograma 1 // Objetivo : Alterar o nome de um frequentador. // Parâmetro : Posição da struct e novo nome // Retorno : Nenhum. void alteraNomeFrequentador(int posicao, char *pNovoNome) { FILE *arq; if (!(arq = fopen(ARQFREQUENT,"r+b"))) // Abrindo com o modo 'Leitura e escrita'. exit(1);//erro ao abrir o arquivo. fseek(arq,posicao,1); fseek(arq,MAX_CPF,1); fwrite(pNovoNome,MAX_NOME,1,arq); fclose(arq); printf("Nome modificado com sucesso!\n"); } // Subprograma 2 // Objetivo : Encontrar uma Struct com o mesmo CPF digitado. // Parâmetro : Cpf Digitado. // Retorno : Posição da estrutura no arquivo. int localizaStructPorCpf(char *pCpfDigitado) { FILE *arq; int contBytes=0; tipoFrequentador estrutura; if (!(arq = fopen(ARQFREQUENT,"rb"))) // Abrindo com o modo 'apenas leitura'. exit(1);//erro ao abrir o arquivo. while(fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { contBytes=ftell(arq); if (strcmp(estrutura.cpf,pCpfDigitado)==0) { fclose(arq); // sempre fechar arquivo return contBytes - sizeof(tipoFrequentador); } } // se saiu o while, quer dizer que não achou nenhum cpf equivalente! fclose(arq); // sempre fechar arquivo return -1; }
Feito isso, você concluiu a alteração de dados. O processo para alterar os outros dados do frequentador é o mesmo, a única coisa que muda é a posição do registro na memória.
Excluindo dados de um arquivo
Suponha que seja necessário deletar um frequentador da academia, para excluir uma struct do arquivo, você deve serguir os seguintes passos:
-Encontrar a struct a ser deletada.
-Criar um arquivo temporário.
-Copiar todos os registros para o arquivo temporário, menos o que será delatado.
-Deletar o arquivo de frequentadores original.
-Renomear o arquivo temporário com o mesmo nome do original.
-Fim.
Vejamos uma função que faz esse processo:
#include<stdio.h> #include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" #define ARQTEMP "frequentadorTemp.bin" //... // Subprograma 1 // Objetivo : Deletar um Frequentador. // Parâmetro : Apontador do frequentador. // Retorno : Nenhum. void deletaFrequentador(int apontador) { //Declaraçoes FILE *arq,*arqTemp; tipoFrequentador estrutura; int contBytes=0; //instruções: if (!(arq = fopen(ARQFREQUENT,"rb"))) exit(1); if (!(arqTemp = fopen(ARQTEMP,"wb"))) exit(1); while(fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { if (contBytes == apontador) fseek(arq,sizeof(tipoFrequentador),1); else fwrite(&estrutura,sizeof(tipoFrequentador),1,arqTemp); contBytes = ftell(arq);//contador de bytes recebendo o apontador. } fclose(arq); fclose(arqTemp); remove(ARQFREQUENT); //Excluindo o arquivo de frequentadores original. rename(ARQTEMP,ARQFREQUENT); printf("Frequentador excluido com sucesso!\n"); return; }
Note que a função recebe como parâmetro somente o apontador do registro, que será obtido pela mesma função que fez isso para alterar dados. Lembre-se! O comando remove só vai funcionar se nenhum arquivo estiver aberto! Agora veja o código completo, que altera ou exclui dados:
#include<stdio.h> #include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" #define ARQTEMP "frequentadorTemp.bin" typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; } tipoFrequentador; //Protótipos: int localizaStructPorCpf(char *pCpfDigitado); void alteraNomeFrequentador(int posicao, char *pNovoNome); void deletaFrequentador(int apontador); int main(void) { // Declaracoes int opcao; int posicaoStruct; char cpfDigitado[MAX_CPF]; tipoFrequentador novaEstrutura; // Instrucoes printf("Digite o cpf do frequentador que deseja alterar:\n"); scanf("%s",cpfDigitado); //Validar CPF! posicaoStruct = localizaStructPorCpf(cpfDigitado); if (posicaoStruct == -1) printf("Nenhum Registro com esse CPF foi encontrado!\n"); else { do { printf("Digite o que voce deseja alterar:\n\n"); printf("1 - Nome\n"); printf("2 - Peso\n"); printf("3 - Sexo\n"); printf("4 - Data de inscricao\n"); printf("5 - DELETAR FREQUENTADOR\n\n"); scanf("%d",&opcao); if ((opcao < 1) || (opcao > 5)) printf("opcao invalida! Digite novamente:\n"); }while((opcao < 1) || (opcao > 5)); switch(opcao) { case 1: { printf("\nDigite o novo nome:\n"); scanf("%s",novaEstrutura.nome); //Validar nome. //Perguntar ao usuario se deseja mesmo alterar... alteraNomeFrequentador(posicaoStruct,novaEstrutura.nome); break; } case 2: { printf("\nDigite o novo peso:\n"); scanf("%f",novaEstrutura.peso); //Validar peso. //Perguntar ao usuario se deseja mesmo alterar... //Chamar a função de alterar peso. break; } case 3: { printf("\nDigite o novo sexo:\n"); scanf("%c",novaEstrutura.sexo); //Validar sexo. //Perguntar ao usuario se deseja mesmo sexo... //Chamar a função de alterar sexo. break; } case 4: { puts("Digite o novo dia:"); scanf("%d",&novaEstrutura.dia); puts("Digite o novo mes:"); scanf("%d",&novaEstrutura.mes); puts("Digite o novo ano:"); scanf("%d",&novaEstrutura.ano); //Validar data //Perguntar ao usuario se deseja mesmo alterar data... //Chamar a função de alterar data. break; } case 5:// deletar frequentador. { deletaFrequentador(posicaoStruct); } } } getch(); return 0; } // Subprograma 1 // Objetivo : Alterar o nome de um frequentador. // Parâmetro : Posição da struct e novo nome // Retorno : Nenhum. void alteraNomeFrequentador(int posicao, char *pNovoNome) { FILE *arq; if (!(arq = fopen(ARQFREQUENT,"r+b"))) exit(1);//erro ao abrir o arquivo. fseek(arq,posicao,1); fseek(arq,MAX_CPF,1); fwrite(pNovoNome,MAX_NOME,1,arq); fclose(arq); printf("Nome modificado com sucesso!\n"); } // Subprograma 2 // Objetivo : Encontrar uma Struct com o mesmo CPF digitado. // Parâmetro : Cpf Digitado. // Retorno : Posição da estrutura no arquivo. int localizaStructPorCpf(char *pCpfDigitado) { FILE *arq; int contBytes=0; tipoFrequentador estrutura; if (!(arq = fopen(ARQFREQUENT,"rb"))) exit(1);//erro ao abrir o arquivo. while(fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { contBytes=ftell(arq); if (strcmp(estrutura.cpf,pCpfDigitado)==0) { fclose(arq); // sempre fechar arquivo return contBytes - sizeof(tipoFrequentador); } } fclose(arq); // sempre fechar arquivo return -1; } // Subprograma 3 // Objetivo : Deletar um Frequentador. // Parâmetro : Apontador do frequentador. // Retorno : Nenhum. void deletaFrequentador(int apontador) { //Declaraçoes FILE *arq,*arqTemp; tipoFrequentador estrutura; int contBytes=0; //instruções: if (!(arq = fopen(ARQFREQUENT,"rb"))) exit(1); if (!(arqTemp = fopen(ARQTEMP,"wb"))) exit(1); while(fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { if (contBytes == apontador) fseek(arq,sizeof(tipoFrequentador),1); else fwrite(&estrutura,sizeof(tipoFrequentador),1,arqTemp); contBytes = ftell(arq);//contador de bytes recebendo o apontador. } fclose(arq); fclose(arqTemp); remove(ARQFREQUENT); rename(ARQTEMP,ARQFREQUENT); printf("Frequentador excluido com sucesso!\n"); return; }
Relacionando todos os frequentadores que executaram pelo menos uma vez uma série de exercício definida pelo usuário:
Para fazer essa relação, a primeira coisa a fazer é pedir ao usuário qual a série que será pesquisada, verificar se ela existe no arquivo de atividades, caso exista, fazer a listagem dos frequentadores que executaram essa atividade com a série informada pelo usuário.
#include<stdio.h> #include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" #define ARQATIVIDADE "dadosAtividades.bin" typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; }tipoFrequentador ; typedef struct { char cpf[MAX_CPF]; int codigo; int dia; int mes; int ano; } tipoAtividade; void listaFrequentadores(tipoFrequentador estrutura); void listaFrequentadoresSerie(int codigoSerie); int main(void) { // Declaracoes int codigoSerie; // Instrucoes printf("Digite o codigo da serie que foi executada:\n"); scanf("%d",&codigoSerie); listaFrequentadoresSerie(codigoSerie); getch(); return 0; } // Subprograma 1 // Objetivo : Fazer a listagem dos frequentadores. // Parâmetro : Estrutura de frequentadores. // Retorno : Nenhum. void listaFrequentadores(tipoFrequentador estrutura) { printf("cpf = %s\n",estrutura.cpf); printf("nome = %s\n",estrutura.nome); printf("peso = %3.2f\n",estrutura.peso); printf("sexo = %c\n",estrutura.sexo); printf("data de inscricao: %d/%d/%d\n\n",estrutura.dia,estrutura.mes,estrutura.ano); } // Subprograma 2 // Objetivo: verificar se algum cliente executou uma serie // Parâmetro: codigo da serie // Retorno: nenhum void listaFrequentadoresSerie(int codigoSerie) { tipoAtividade atividades; tipoFrequentador frequentadores; FILE *arqAtividade, *arqFrequentador; int contador=0; if (!(arqAtividade = fopen(ARQATIVIDADE,"a+b"))) exit(1); if (!(arqFrequentador = fopen(ARQFREQUENT,"rb"))) exit(1); while (fread(&atividades,sizeof(tipoAtividade),1,arqAtividade)) { if (atividades.codigo == codigoSerie) { rewind(arqFrequentador); while (fread(&frequentadores,sizeof(tipoFrequentador),1,arqFrequentador)) { if (frequentadores.cpf == atividades.cpf) { listaFrequentadores(frequentadores); contador++; } } } } fclose(arqAtividade); fclose(arqFrequentador); if (!contador) printf("nenhum frequentador executou essa atividade!"); }
Lembre-se: para essa operação funcionar, seu código já deve ter a struct de atividades implementada!
Pesquisando os frequentadores matriculados na academia pelo nome:
A primeira coisa a fazer é pedir o nome a ser pesquisado pelo usuário, depois é só ler todos os registros do arquivo, comparar o nome digitado (usando a função strstr) com os nomes do arquivo e fazer a listagem dos nomes que são semelhantes ao que o usuário digitou. Observe a função que realiza essa operação:
// Subprograma 1 // Objetivo : Pesquisar nomes semelhantes ao digitado. // Parâmetro : Nome digitado. // Retorno : Nenhum. void pesquisaNomeSemelhante(char *pNome) { FILE *arq; tipoFrequentador estrutura; int contador=0; if (!(arq = fopen(ARQFREQUENT,"rb"))) exit(1); while (fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { if (strstr(estrutura.nome,pNome)) { listaFrequentadores(estrutura); contador++; } } if (!contador) printf("nenhum frequentador com esse nome foi encontrado!\n"); }
Note que todos os registros do arquivo são lidos, e quando um semelhante ao digitado é encontrado, a função que faz a listagem é chamada, veja o corpo dela:
// Subprograma 2 // Objetivo : Fazer a listagem dos frequentadores. // Parâmetro : Estrutura de frequentadores. // Retorno : Nenhum. void listaFrequentadores(tipoFrequentador estrutura) { printf("cpf = %s\n",estrutura.cpf); printf("nome = %s\n",estrutura.nome); printf("peso = %3.2f\n",estrutura.peso); printf("sexo = %c\n",estrutura.sexo); printf("data de inscricao: %d/%d/%d\n",estrutura.dia,estrutura.mes,estrutura.ano); }
Agora veja um exemplo de código que pede para o usuário digitar um nome, e então faz a pesquisa:
#include <stdio.h>#include <conio.c> #define MAX_CPF 12 #define MAX_NOME 60 #define ARQFREQUENT "dadosFrequentadores.bin" typedef struct { char cpf[MAX_CPF]; char nome[MAX_NOME]; float peso; char sexo; int dia,mes,ano; } tipoFrequentador; void pesquisaNomeSemelhante(char *pNome); void listaFrequentadores(tipoFrequentador estrutura); int main(void) { // Declaracoes char nomeDigitado[MAX_NOME]; // Instrucoes printf("Digite o nome ou parte dele a ser pesquisado:\n"); scanf("%s",nomeDigitado); pesquisaNomeSemelhante(nomeDigitado); getch(); return 0; } // Subprograma 1 // Objetivo : Pesquisar nomes semelhantes ao digitado. // Parâmetro : Nome digitado. // Retorno : Nenhum. void pesquisaNomeSemelhante(char *pNome) { FILE *arq; tipoFrequentador estrutura; int contador=0; if (!(arq = fopen(ARQFREQUENT,"rb"))) exit(1); while (fread(&estrutura,sizeof(tipoFrequentador),1,arq)) { if (strstr(estrutura.nome,pNome)) { listaFrequentadores(estrutura); contador++; } } if (!contador) printf("nenhum frequentador com esse nome foi encontrado!\n"); } // Subprograma 2 // Objetivo : Fazer a listagem dos frequentadores. // Parâmetro : Estrutura de frequentadores. // Retorno : Nenhum. void listaFrequentadores(tipoFrequentador estrutura) { printf("cpf = %s\n",estrutura.cpf); printf("nome = %s\n",estrutura.nome); printf("peso = %3.2f\n",estrutura.peso); printf("sexo = %c\n",estrutura.sexo); printf("data de inscricao: %d/%d/%d\n",estrutura.dia,estrutura.mes,estrutura.ano); }