Ir ao conteúdo
  • Cadastre-se
dnlch1

C comparar int em files

Posts recomendados

Boa noite pessoal, 

 

Seguinte, eu preciso fazer um programa onde eu faco o cadastro de varias pessoas e depois tenho que informar e comparar o mes e ano de aniversario, e na tela precisa mostrar os registros das pessoas que fazer aniversario naqueles mes e ano respectivo.

 

Segue code: 

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

    struct reg_pessoa
    {
        char nome[30];
        int dia,mes,ano;
    };

    FILE *parq;
    struct reg_pessoa p;

    void abrir_arquivo()
    {
      parq = fopen("teste","ab+");
      if(parq == NULL){
        printf("Erro ao acessar o arquivo");
      }
      else{
        printf("Arquivo aberto com sucesso");
      }
    }

     void ler_arquivo()
     {
      parq = fopen("teste","r");
      if(parq == NULL){
        printf("Erro ao acessar o arquivo");
      }
      else{
        printf("Arquivo lido com sucesso\n");
      }
     }

    void leitura()
    {
        int i;
        char nome;
        long tamanho;
        int op;
        int excluido = 1;


         do{
            printf("\nREGISTRO \n");
            printf("Informe o nome\n");
            scanf("%s", &p.nome);
            printf("Informe o dia \n");
            scanf("%i",&p.dia);
            printf("Informe o mes \n");
            scanf("%i",&p.mes);
            printf("Informe o ano \n");
            scanf("%i", &p.ano);
            op = resposta();
            escreverNoArquivo(p,parq);
            tamanho++;
         }while (op != 'N');

            fclose(parq);
         }

         void listar_nascidos()
    {
        int logico = 0;
        long tamanho;
        char r;
        int mes,ano;
        struct reg_pessoa p;


            printf("Informe o mes ");
            scanf("%i", &mes);
            printf("Informe o ano ");
            scanf("%i", &ano);

        while (parq != EOF)
        {
            fread(&p,sizeof(struct reg_pessoa),1,parq);
            if (mes == p.mes && ano == p.ano && logico == 0)
            {
                printf("pessoas nascidas:");
                printf("nome",p.nome);
                printf("dia",p.dia);
                printf("mes",p.mes);
                printf("ano",p.ano);
                logico = 1;
                logico++;
                fseek(parq, (tamanho)*sizeof(struct reg_pessoa), SEEK_SET);
                fwrite(&p, sizeof(struct reg_pessoa), 1, parq);
            }
            else
            {
                printf("Nao ha pessoas nascidas");
            }
        }
            fclose(parq);
    }

      void listar_nascidos()
    {
        int logico = 0;
        long tamanho;
        char r;
        int dia,mes,ano;
        fseek(parq,sizeof(p),SEEK_END);
        tamanho = (ftell(parq)/sizeof(p))-2;

        do{
            printf("Informe o dia ");
            scanf("%i", &dia);
            printf("Informe o mes ");
            scanf("%i", &mes);
            printf("Informe o ano ");
            scanf("%i", &ano);

        while (feof(parq) == 0 && logico == 0)
        {
            fread(&p,sizeof(struct reg_pessoa),1,parq);
            if (mes == p.mes && ano == p.ano && logico == 0)
            {
                logico++;
                printf("pessoas nascidas:");
                printf("nome",p.nome);
                printf("dia",p.dia);
                printf("mes",p.mes);
                printf("ano",p.ano);
                logico = 1;
            }
            else
            {
                printf("Nao ha pessoas nascidas");
            }
        }
            }while(r == 'N');
            fclose(parq);
    }



    void main()
    {
        abrir_arquivo();
        leitura();
        listar_nascidos();


        return 0;
    }

    void resposta()
{
    char resp;

    printf ("\nDeseja Continuar <S/N> ?");

    do
    {
        scanf("%c", &resp);
    }while (resp!='S' && resp!='N');

    return (resp);
}


void escreverNoArquivo(struct reg_pessoa p, FILE *arq)
{
    long N;
    N=(ftell(parq)/sizeof(struct reg_pessoa)-1);
    fseek(parq,N*sizeof(struct reg_pessoa),SEEK_CUR);


    if(parq != NULL)
    {
        fwrite(&p, sizeof(struct reg_pessoa), 1, parq);
    }
    else
    {
        printf("\nErro ao abrir o arquivo para escrita!\n");
        exit(1); // aborta o programa
    }
}

 

O cadastro esta dando certo, problema eh no procedimento listar_contatos(), eu ja fiz 2 procedimentos mas nenhum esta dando certo. Preciso de ajuda para fazer essa comparacao de um campo da minha struct com as variaveis locais do listar_contatos. 

 

Obrigado desde ja

OBS: Nao posso utilizar vetor.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@dnlch1    seu código está bom , e para listar você precisa abrir o arquivo ,  então ajeitei para que ele faça essa listagem  e seu código ficou assim  :

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#define cls system("cls");
struct reg_pessoa{
    char nome[30];
    int dia,mes,ano;
};
FILE *parq;
struct reg_pessoa p;
char resposta();/* precisa ser char pois vai retornar algo */
void escreverNoArquivo(struct reg_pessoa p, FILE *arq);
void abrir_arquivo(){
    parq=fopen("teste.bin","ab+");/* se não existir cria e abre para gravação */
    if(parq==NULL)
        printf("Erro ao Criar o arquivo !\n");
    else
        printf("Arquivo aberto para Gravacao,  com sucesso . . . !\n");
    fclose(parq);
}
void ler_arquivo(){
    fopen("teste.bin","rb");
    if(parq == NULL)
        printf("Erro ao acessar o arquivo !\n");
    else
        printf("Arquivo lido com sucesso . . . !\n");
}
void leitura(){
    int i,excluido=1;
    char nome,op;
    long tamanho;/* aqui toda vez ele vai mudar o valor , e como não
          foi inicializado terá valor insabido , o mesmo que lixo */
    parq=fopen("teste.bin","ab");/* abre para gravação ou leitura */
    do{
        printf("\nREGISTRO\n");
        printf("Informe o nome ");
        fflush(stdin);               /* limpar buffer do teclado */
        scanf("%s",p.nome);          /* só pega o primeiro nome , para pegar os sobrenomes use gets
                                       e sem & , pois string já é um ponteiro para a posição da memória */
        printf("Informe o dia ");
        fflush(stdin);               /* limpar buffer do teclado */
        scanf("%d",&p.dia);          /* geralmente se usa a letra d de decimal */
        printf("Informe o mes ");
        fflush(stdin);               /* limpar buffer do teclado */
        scanf("%i",&p.mes);
        printf("Informe o ano ");
        fflush(stdin);               /* mudou o tipo limpe o buffer */
        scanf("%i",&p.ano);
        op = resposta();
        escreverNoArquivo(p,parq);   /* arquivo está aberto para gravaçao e leitura */
        tamanho++;                   /* não está servindo para nada */
    }while(toupper(op) != 'N');
    fclose(parq);
}
void listar_nascidos(){
    parq=fopen("teste.bin","rb");
    int logico = 0,mes,ano;
    long tamanho;
    char r;
    struct reg_pessoa p;
    printf("Informe o mes ");
    scanf("%i",&mes);
    printf("Informe o ano ");
    scanf("%i",&ano);
    while(fread(&p,sizeof(struct reg_pessoa),1,parq) ==1){
        if (mes == p.mes && ano == p.ano /*&& logico == 0*/){/* aqui lista o primero com essa data */
            printf("pessoas nascidas :\n");
            printf("nome --: %s\n",p.nome);
            printf("dia ---: %d\n",p.dia);
            printf("mes ---: %d\n",p.mes);
            printf("ano ---: %d\n",p.ano);
            logico = 1; /* aqui informa para ler apenas um , pois muda o valor de logico*/
            /*logico++;   /* se retirar esse logico , vai listar todos dessa data         */
            /*fseek(parq, (tamanho)*sizeof(struct reg_pessoa), SEEK_SET);
            fwrite(&p, sizeof(struct reg_pessoa), 1, parq);*/
        }
        /*else{
            if( ! logico )printf("Nao ha pessoas nascidas");
        }*/
    }
    if( ! logico )printf("Nao ha pessoas nascidas nessa data\n");
    fclose(parq);
    printf("     Tecle !");
    getch();
}
void listar_nascidos_2(){
    int logico = 0;
    long tamanho;
    char r;
    int dia,mes,ano;
    fseek(parq,sizeof(p),SEEK_END);
    tamanho = (ftell(parq)/sizeof(p))-2;
    do{
        printf("Informe o dia ");
        scanf("%i", &dia);
        printf("Informe o mes ");
        scanf("%i", &mes);
        printf("Informe o ano ");
        scanf("%i", &ano);
        while (feof(parq) == 0 && logico == 0){
            fread(&p,sizeof(struct reg_pessoa),1,parq);
            if (mes == p.mes && ano == p.ano && logico == 0){
                logico++;
                printf("pessoas nascidas:");
                printf("nome",p.nome);
                printf("dia",p.dia);
                printf("mes",p.mes);
                printf("ano",p.ano);
                logico = 1;
            }
            else{
                printf("Nao ha pessoas nascidas");
            }
        }
    }while(r == 'N');
    fclose(parq);
}
void listar_todos_nascidos(){
    parq=fopen("teste.bin","rb");
    while(fread(&p,sizeof(struct reg_pessoa),1,parq)==1){
        printf("\n pessoas nascidas :\n\n");
        printf("nome --: %s  \n",p.nome   );
        printf("dia ---: %d  \n",p.dia    );
        printf("mes ---: %d  \n",p.mes    );
        printf("ano ---: %d\n\n",p.ano    );
    }
    fclose(parq);
    printf("     Tecle !");
    getch();
}
int main(){    /* melhor que seja int pois precisa retornar algo */
    int sair;
    abrir_arquivo();/* cria ou abre o arquivo */
    printf("    Tecle !");
    getch();
    do{
        cls;
        printf(" 1 - cadastrar\n");
        printf(" 2 - listar por Data\n");
        printf(" 3 - listar Todos\n");
        printf(" 4 - Sair\n");
        printf("     escolha ");
        scanf("%d",&sair);
        switch(sair){
        case 1:
            leitura();
            break;
        case 2:
            listar_nascidos();
            break;
        case 3:
            listar_todos_nascidos();
            break;
        case 4:
            printf("\nSaindo . . . !\n");
            break;
        }
    }while( sair != 4 );
    return 0;
}
char resposta(){
    char resp;
    printf ("\nDeseja Continuar < S / N > ?");
    do{
        fflush(stdin);
        scanf("%c",&resp);
    }while(toupper(resp) != 'S' && toupper(resp) != 'N' );
    return resp;
}
void escreverNoArquivo(struct reg_pessoa p, FILE *arq){
    long N;
    /*N=(ftell(parq)/sizeof(struct reg_pessoa)-1);
    fseek(parq,N*sizeof(struct reg_pessoa),SEEK_CUR);*/
    if(parq != NULL){
        fwrite(&p, sizeof(struct reg_pessoa), 1, parq);
    }
    else{
        printf("\nErro ao abrir o arquivo para escrita!\n");
        exit(1); // aborta o programa
    }
}

 

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite Devair, obrigado pela resposta e curti as mudanças, ficou bem mais claro e estruturado. 

 

Eu fiz um teste para ver, quando iniciado o lista_contatos(), ele mostra sempre o primeiro que faz aniversario naquele mes e ano, e nao mostra a segunda pessoa, e ainda aparece a mensagem nao ha pessoas(em anexo).

Quando substitui pelo lista_contatos_2(), nao aparece nada quando escolhe a opcao listar.

 

 

Capture.PNG

  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@dnlch1     essa função ->  lista_contatos_2() não tem nesse código não ,  mas creio que você quis dizer listar_nascidos_2() ,  e ela não está funcionando pois não abre o arquivo para ler nele , e creio que o controle de final de arquivo não funcione daquele jeito ,  melhor usar como no listar_nascidos lá de cima ,  e ele imprime esse monte de  nao ha pessoas nascidas   porque em todos os ciclos do loop while ele escreve assim , então use um controle para imprimir depois do loop while , assim só vai imprimir uma vez e se não houver nenhum mesmo ,  e havendo pelo menos hum ele não imprimirá isso  ,  e necessita de  outras modificações   ,  mas precisa de tempo , código demorado , uma ou duas semanas ,  mas modifiquei o código que postei ali acima incluindo uma fução para listar todos ,  copie e teste novamente    .

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia,

 

Estava com muito sono kkkkk, ja n tava vendo mais nada. 

 

Vou fazer umas mudancas, postarei aqui novamente quando tiver 100%. 

 

Obrigado pela ajuda! 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Devair, eu alterei algumas coisas, e funcionou legal a opcao de listar todos. porém na opcao de comparar e mostrar os aniversariantes de mesmo mes e ano, so aparece o ultimo cadastrado. Eu entendi que quando o mudei o valor da variavel logico, ele so puxa o ultimo, mas nao to sabendo como fazer de outro jeito ou arrumar isso... Eu fiz outro if para mostrar apenas os contatos com valor logico == 1... 

 

void listar_nascidos(){
    parq=fopen("teste.bin","rb");
    int logico = 0,mes,ano;
    long tamanho;
    char r;
    int i;
    struct reg_pessoa p;
    printf("Informe o mes ");
    scanf("%i",&mes);
    printf("Informe o ano ");
    scanf("%i",&ano);
    printf("pessoas nascidas :\n");

     while(fread(&p,sizeof(struct reg_pessoa),1,parq) == 1){
        if (mes == p.mes && ano == p.ano && logico == 0){/* aqui lista o primero com essa data */
            logico =+ 1;
            /*logico = 1; /* aqui informa para ler apenas um , pois muda o valor de logico*/
            /*logico++;   /* se retirar esse logico , vai listar todos dessa data         */
            /*fseek(parq, (tamanho)*sizeof(struct reg_pessoa), SEEK_SET);
            fwrite(&p, sizeof(struct reg_pessoa), 1, parq);*/
        }
        /*else{
            if( ! logico )printf("Nao ha pessoas nascidas");
        }*/
    }
    if(logico > 0)
    {
        for(i=0;i<2;i++){
        if(mes == p.mes && ano == p.ano)
        {
            printf("nome --: %s\n",p.nome);
            printf("dia ---: %d\n",p.dia);
            printf("mes ---: %d\n",p.mes);
            printf("ano ---: %d\n",p.ano);
    }
        }
        }
        if( logico == 0 )
        {
            printf("Nao ha pessoas nascidas nessa data\n");
        }
    fclose(parq);
    printf("     Tecle !");
    getch();
}

 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá

 

Notei que não usa parâmetros em suas funções. É de propósito ou ainda não aprendeu isso?

Veja essas duas funções por exemplo:

void abrir_arquivo()
{
    parq = fopen("teste", "ab+");
    if (parq == NULL) {
        printf("Erro ao acessar o arquivo");
    }
    else {
        printf("Arquivo aberto com sucesso");
    }
}

void ler_arquivo()
{
    parq = fopen("teste", "r");
    if (parq == NULL) {
        printf("Erro ao acessar o arquivo");
    }
    else {
        printf("Arquivo lido com sucesso\n");
    }
}

Podia escrever

void abre_arquivo(char* modo)
{
    parq = fopen("teste", modo);
    if (parq == NULL) {
        printf("Erro ao acessar o arquivo");
    }
    else {
        printf("Arquivo lido com sucesso\n");
    }
}

E se entendeu isso, aí pode entender que é melhor não misturar a lógica com o processamento de arquivo e pode tirar a leitura de valores da função de listar_nascidos() por exemplo, e fica muito mais fácil e rápido para testar. Use por exemplo

 

void listar_nascidos(int mes, int ano);

 

E use um parâmetro inválido para listar todos, (tipo mes == 0).

Assim pode chamar direto

listar_nascidos(0,0);
listar_nascidos(10,90);

por exemplo, em seus testes

 


 

adicionado 4 minutos depois

resposta() não pode ser declarado como void se pretende retornar um char, então use

 

char resposta();

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

@dnlch1       testei aqui no codeblocks 16.01 e está mostrando todos os nascidos na data indicada  , e desse jeito que você colocou ele só vai mostrar mesmo o último pois ali onde estão essas linhas , já saiu do loop while e as variáveis estão com os valores que pegaram por último ,  então para imprimir precisa ser dentro de loop while , essa função aqui me parace boa  :

void listar_nascidos(){
    parq = fopen("teste.bin","rb");
    int mes,ano,logico=0;
    struct reg_pessoa p;
    printf("Informe o mes ");
    scanf("%d",&mes);
    printf("Informe o ano ");
    scanf("%d",&ano);                  /* é costume usar a letra d de decimal */
    while(fread(&p,sizeof(struct reg_pessoa),1,parq) ==1){
        if( mes == p.mes && ano == p.ano   ){
            printf("pessoas nascidas :\n"  );
            printf("nome --: %s\n  ",p.nome);
            printf("dia ---: %d\n  ",p.dia );
            printf("mes ---: %d\n  ",p.mes );
            printf("ano ---: %d\n\n",p.ano );
            logico = 1; /* aqui informa para ler apenas um , pois muda o valor de logico*/
        }
    }
    if( ! logico )printf("Nao ha pessoas nascidas nessa data\n");
    fclose(parq);
    printf("     Tecle !");
    getch();
}

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite Devair, 

 

Consegui arrumar com a ajuda de um amigo, criei uma variável soma e coloquei mais um while().

 

Obrigado pela ajuda Devair e Arfneto.

 

void listar_nascidos(){
    int logico = 0,mes,ano;
    long tamanho;
    char r;
    int soma = 0;
    struct reg_pessoa p;

    parq=fopen("teste.bin","rb");

    printf("Informe o mes ");
    scanf("%i",&mes);
    printf("Informe o ano ");
    scanf("%i",&ano);
    while(1){
    fread(&p,sizeof(struct reg_pessoa),1,parq);
    if (feof(parq)) break;
        if (mes == p.mes && ano == p.ano && valido == 1){
            if(logico == 0){
                logico = 1;
                printf("pessoas nascidas no mesmo mes e ano :\n");
                printf("Nome ---| %s\n", p.nome);
                printf("Dia ---| %d\n", p.dia);
                printf("Mes ---| %d\n",p.mes);
                printf("Ano ---| %d\n",p.ano);
            } else {

            printf("Nome ---|  %s\n",p.nome);
            printf("Dia ---| %d\n",p.dia);
            printf("Mes ---| %d\n",p.mes);
            printf("Ano ---| %d\n",p.ano);
            /*logico = 1; /*
            /*logico++;   /*
            /*fseek(parq, (tamanho)*sizeof(struct reg_pessoa), SEEK_SET);
            fwrite(&p, sizeof(struct reg_pessoa), 1, parq);*/
        }soma += 1;
        /*else{
            if( ! logico )printf("Nao ha pessoas nascidas");
        }*/
        }

    }
    if( soma == 0 )printf("Nao ha pessoas nascidas nessa data\n");
    fclose(parq);
    printf("     Tecle !");
    getch();
}

 

Pode fechar o tópico 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

 

Parabéns! Bom que o programa rodou ok afinal. 

 

Vou te mostrar um exemplo de como tratar isso do jeito que eu te falei acima. Apenas porque agora fica fácil de você comparar porque já sabe o trabalho que teve e talvez possa usar isso no futuro.

 

Testar programas que tem menus e leem coisas da tela é sempre chato e lento. Essa é uma razão pra não fazer essas coisas nunca ao mesmo tempo. 

 

Como começar então?

O programa é isso: Temos uma estrutura e vamos criar um arquivo com os registros que o usuário criou numa primeira fase do programa, um a um. E depois vamos ler os dados do disco e filtrar por um critério, o mês e ano de nascimento das pessoas cadastradas. Imagine uma fictícia função declarada assim:
 

int        xyz_grava_uns(FILE* file, int ano, int quantos_anos, int quantos_por_mes, int maximo);

Onde

 

file - o ponteiro para o arquivo já aberto
ano -  o primeiro ano de nascimento das pessoas
quantos_anos - registros para quantos anos a partir de ano.
quantos_por_mes - quantos registros de pessoas nascidas em cada mês vão ser gerados
maximo - total maximo de registros a gerar, só pra evitar algum exagero inesperado

 

E os nomes dos caras? são do tipo 'Nome XYZnnnn' numerados a partir de um. Assim fica fácil acompanhar se algo está duplicando sem ter que inventar nada..

 

E a função retorna o número de registros efetivamente gravados no disco que seria uma próxima pergunta.

 

Exemplo 1   

int total = xyz_grava_uns(arquivo, 2010, 1, 2, 1000); 

Vai gerar um arquivo contendo nascidos a partir de 2010, 1 único ano então apenas esse, 2 por mês, e um máximo de 1000 registros. vai gerar 24, claro: 2 por mês, 12 meses, 1 ano. E o arquivo vai estar lá enquanto você testa outras partes do programa, ao invés de ficar A CADA TESTE rodando um menu e inventando nomes meses e anos e tal

 

Exemplo 2

 int total = xyz_grava_uns(arquivo, 2010, 10, 20, 1000);   

Vai gerar registros, 20 por mês  para cada mês a partir de 2010, mas parando no registro 1000 porque iria passar do limite estipulado

 

Uma possível função

int        xyz_grava_uns(FILE* file, int ano, int quantos_anos, int quantos_por_mes, int maximo)
{
    int           sequencia = 1;
    Pessoa        modelo;
    modelo.dia = 1;                        // nao faz diferenca no teste

    if (file == NULL) return -1;
    for (int a = 0; a < quantos_anos; a += 1)
    {
        modelo.ano = ano + a;            // cria registros para esse ano
        for (int m = 1; m <= 12; m += 1)
        {
            modelo.mes = m;                // cria para esse mes
            for (int n = 0; n < quantos_por_mes; n += 1)
            {
                sprintf(modelo.nome, "Nome XYZ%04d", sequencia);
                printf(
                    "%03d: '%s'nascido em %02d/%02d/%04d\n", sequencia,
                    modelo.nome, modelo.dia, modelo.mes, modelo.ano
                );
                fwrite(&modelo, sizeof(Pessoa), 1, file);
                if (sequencia >= maximo) return 0;
                sequencia = sequencia + 1;
            }    // for n
        }    // for m
    }    // for a
    return sequencia - 1;
};    // xyz_grava_uns()

Eis o que ela mostra para o exemplo 1

Arquivo coisa.txt aberto com sucesso
001: 'Nome XYZ0001'nascido em 01/01/2010
002: 'Nome XYZ0002'nascido em 01/01/2010
003: 'Nome XYZ0003'nascido em 01/02/2010
004: 'Nome XYZ0004'nascido em 01/02/2010
005: 'Nome XYZ0005'nascido em 01/03/2010
006: 'Nome XYZ0006'nascido em 01/03/2010
007: 'Nome XYZ0007'nascido em 01/04/2010
008: 'Nome XYZ0008'nascido em 01/04/2010
009: 'Nome XYZ0009'nascido em 01/05/2010
010: 'Nome XYZ0010'nascido em 01/05/2010
011: 'Nome XYZ0011'nascido em 01/06/2010
012: 'Nome XYZ0012'nascido em 01/06/2010
013: 'Nome XYZ0013'nascido em 01/07/2010
014: 'Nome XYZ0014'nascido em 01/07/2010
015: 'Nome XYZ0015'nascido em 01/08/2010
016: 'Nome XYZ0016'nascido em 01/08/2010
017: 'Nome XYZ0017'nascido em 01/09/2010
018: 'Nome XYZ0018'nascido em 01/09/2010
019: 'Nome XYZ0019'nascido em 01/10/2010
020: 'Nome XYZ0020'nascido em 01/10/2010
021: 'Nome XYZ0021'nascido em 01/11/2010
022: 'Nome XYZ0022'nascido em 01/11/2010
023: 'Nome XYZ0023'nascido em 01/12/2010
024: 'Nome XYZ0024'nascido em 01/12/2010
gravados 24 registros

E para listar?

Imagine uma função

int        xyz_filtra_uns(FILE* file, int mes, int ano);


Você chama passando um mês e ano e ela vai no arquivo e lista os que satisfazem o critério. E retorna quantos ela leu. 

Se passar um ano ou mês inválido ela lista todo mundo assim não precisamos escrever outra função pra isso. Afinal a primeira coisa que vamos querer testar é se está lendo e gravando certo.

 

O critério para o filtro é simples:

Lista se

  • o mês é inválido
  • o ano é inválido
  • o cara nasceu no mês e ano fornecido

Veja um exemplo da função

int        xyz_filtra_uns(FILE* file, int mes, int ano)
{
    Pessoa    modelo;
    int       sequencia = 1;
    int       esse_sim = 0;
    // lista todo mundo que nasceu nesse mes e ano. Se
    // os valores forem invalidos lista todo mundo
    while ( 1 == fread(&modelo, sizeof(Pessoa), 1, file))    
    {
        // fread() retorna 1 se leu uma Pessoa
        /*
         aqui entra o criterio: lido ja foi: se passar pelo filtro
         mostra. se o mes ou o ano forem invalidos lista todo mundo
         assim não precsia escrever outra funcao e podemos testar 
         logo de uma vez
         */
        esse_sim = 0;
        if ((mes < 1) || (mes > 12)) esse_sim = 1;    // 
        if ((ano < 1919) || (ano > 2019) ) esse_sim = 1;    //
        if ((modelo.mes == mes) && (modelo.ano == ano)) esse_sim = 1;
        if( esse_sim )
        {
            printf(
                "%03d: '%s'nascido em %02d/%02d/%04d\n", sequencia,
                modelo.nome, modelo.dia, modelo.mes, modelo.ano
            );
            sequencia += 1;
        }
    }    // while
    return sequencia - 1;
}    // xyz_filtra_uns()

Eis um programa de teste usando essas funções

 

Criando o arquivo

    int        total;

    arquivo = xyz_abrir_arquivo("coisa.txt", "w");    // abre para gravar os caras
    total = xyz_grava_uns(arquivo, 2010, 1, 2, 1000);    // grava
    printf("gravados %d registros\n", total);
    fclose(arquivo);                                    // fecha

Mostraria 

Arquivo coisa.txt aberto com sucesso
001: 'Nome XYZ0001'nascido em 01/01/2010
002: 'Nome XYZ0002'nascido em 01/01/2010
003: 'Nome XYZ0003'nascido em 01/02/2010
004: 'Nome XYZ0004'nascido em 01/02/2010
005: 'Nome XYZ0005'nascido em 01/03/2010
006: 'Nome XYZ0006'nascido em 01/03/2010
007: 'Nome XYZ0007'nascido em 01/04/2010
008: 'Nome XYZ0008'nascido em 01/04/2010
009: 'Nome XYZ0009'nascido em 01/05/2010
010: 'Nome XYZ0010'nascido em 01/05/2010
011: 'Nome XYZ0011'nascido em 01/06/2010
012: 'Nome XYZ0012'nascido em 01/06/2010
013: 'Nome XYZ0013'nascido em 01/07/2010
014: 'Nome XYZ0014'nascido em 01/07/2010
015: 'Nome XYZ0015'nascido em 01/08/2010
016: 'Nome XYZ0016'nascido em 01/08/2010
017: 'Nome XYZ0017'nascido em 01/09/2010
018: 'Nome XYZ0018'nascido em 01/09/2010
019: 'Nome XYZ0019'nascido em 01/10/2010
020: 'Nome XYZ0020'nascido em 01/10/2010
021: 'Nome XYZ0021'nascido em 01/11/2010
022: 'Nome XYZ0022'nascido em 01/11/2010
023: 'Nome XYZ0023'nascido em 01/12/2010
024: 'Nome XYZ0024'nascido em 01/12/2010
gravados 24 registros

Lista todo mundo 

    arquivo = xyz_abrir_arquivo("coisa.txt", "r");    // abre para ler
    total = xyz_filtra_uns(arquivo, 0, 0);        // mes ou ano invalido lista todo mundo
    printf("lidos %d registros\n", total);
    fclose(arquivo);

Mostraria

Arquivo coisa.txt aberto com sucesso
001: 'Nome XYZ0001'nascido em 01/01/2010
002: 'Nome XYZ0002'nascido em 01/01/2010
003: 'Nome XYZ0003'nascido em 01/02/2010
004: 'Nome XYZ0004'nascido em 01/02/2010
005: 'Nome XYZ0005'nascido em 01/03/2010
006: 'Nome XYZ0006'nascido em 01/03/2010
007: 'Nome XYZ0007'nascido em 01/04/2010
008: 'Nome XYZ0008'nascido em 01/04/2010
009: 'Nome XYZ0009'nascido em 01/05/2010
010: 'Nome XYZ0010'nascido em 01/05/2010
011: 'Nome XYZ0011'nascido em 01/06/2010
012: 'Nome XYZ0012'nascido em 01/06/2010
013: 'Nome XYZ0013'nascido em 01/07/2010
014: 'Nome XYZ0014'nascido em 01/07/2010
015: 'Nome XYZ0015'nascido em 01/08/2010
016: 'Nome XYZ0016'nascido em 01/08/2010
017: 'Nome XYZ0017'nascido em 01/09/2010
018: 'Nome XYZ0018'nascido em 01/09/2010
019: 'Nome XYZ0019'nascido em 01/10/2010
020: 'Nome XYZ0020'nascido em 01/10/2010
021: 'Nome XYZ0021'nascido em 01/11/2010
022: 'Nome XYZ0022'nascido em 01/11/2010
023: 'Nome XYZ0023'nascido em 01/12/2010
024: 'Nome XYZ0024'nascido em 01/12/2010
lidos 24 registros

Lista os que nasceram em 09/2010

    // ja que deu certo listar todos vamos testar com um intervalo
    arquivo = xyz_abrir_arquivo("coisa.txt", "r");    // abre para ler
    total = xyz_filtra_uns(arquivo, 9, 2010);        // setembro de 2010
    printf("\"filtrados\" %d registros\n", total);
    fclose(arquivo);

Mostraria

Arquivo coisa.txt aberto com sucesso
001: 'Nome XYZ0017'nascido em 01/09/2010
002: 'Nome XYZ0018'nascido em 01/09/2010
"filtrados" 2 registros

Tenta listar os que nasceram em 09/2018, e não deve ter nenhum

    // e testamos para um valor que nao tem no arquivo
    arquivo = xyz_abrir_arquivo("coisa.txt", "r");    // abre para ler
    total = xyz_filtra_uns(arquivo, 9, 2018);        // setembro de 2010
    printf("\"filtrados\" %d registros\n", total);
    fclose(arquivo);

Mostraria

Arquivo coisa.txt aberto com sucesso
"filtrados" 0 registros

Claro que esses testes todos são apenas recortar e colar e mudar um parâmetro, e você testa um por vez.

E partir daí assim você pode continuar com o programa sabendo que vai ler, gravar e filtrar, sem perder tempo com menu, cursor, cores, seek(), rewind() ftell(), scanf(), abrir e fechar arquivos e tal. De modo similar você escreve o resto, menu, cadastro e fim.

Eis o programa de teste

#define			_CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct reg_pessoa
{
	char nome[30];
	int dia, mes, ano;
};
typedef struct reg_pessoa		Pessoa;

FILE*		arquivo;
Pessoa		p;

FILE*	xyz_abrir_arquivo(char* nome, char* modo);
int		xyz_filtra_uns(FILE*, int mes, int ano);	
int		xyz_grava_uns(FILE* file, int ano, int quantos_anos, int quantos_por_mes, int maximo);


int main( int argc, char** argv )
{
	int		total;

	arquivo = xyz_abrir_arquivo("coisa.txt", "w");	// abre para gravar os caras
	total = xyz_grava_uns(arquivo, 2010, 1, 2, 1000);	// grava
	printf("gravados %d registros\n", total);
	fclose(arquivo);									// fecha

	arquivo = xyz_abrir_arquivo("coisa.txt", "r");	// abre para ler
	total = xyz_filtra_uns(arquivo, 0, 0);		// mes ou ano invalido lista todo mundo
	printf("lidos %d registros\n", total);
	fclose(arquivo);

	// ja que deu certo listar todos vamos testar com um intervalo
	arquivo = xyz_abrir_arquivo("coisa.txt", "r");	// abre para ler
	total = xyz_filtra_uns(arquivo, 9, 2010);		// setembro de 2010
	printf("\"filtrados\" %d registros\n", total);
	fclose(arquivo);

	// e testamos para um valor quenao tem no arquivo
	arquivo = xyz_abrir_arquivo("coisa.txt", "r");	// abre para ler
	total = xyz_filtra_uns(arquivo, 9, 2018);		// setembro de 2010
	printf("\"filtrados\" %d registros\n", total);
	fclose(arquivo);

	return 0;
}


FILE*		xyz_abrir_arquivo(char* nome, char* modo)
{
	arquivo = fopen(nome, modo);
	if (arquivo == NULL)
	{
		perror("Erro ao tentar abrir o arquivo");
	}
	else
	{
		printf("Arquivo %s aberto com sucesso\n", nome);
	};
	return arquivo;
};


int		xyz_filtra_uns(FILE* file, int mes, int ano)
{
	Pessoa	modelo;
	int		sequencia = 1;
	int		esse_sim = 0;
	// lista todo mundo que nasceu nesse mes e ano. Se
	// os valores forem invalidos lista todo mundo
	while ( 1 == fread(&modelo, sizeof(Pessoa), 1, file))	
	{
		// fread() retorna 1 se leu uma Pessoa
		/*
		 aqui entra o criterio: lido ja foi: se passar pelo filtro
		 mostra. se o mes ou o ano forem invalidos lista todo mundo
		 assim não precsia escrever outra funcao e podemos testar 
		 logo de uma vez
		 */
		esse_sim = 0;
		if ((mes < 1) || (mes > 12)) esse_sim = 1;	// 
		if ((ano < 1919) || (ano > 2019) ) esse_sim = 1;	//
		if ((modelo.mes == mes) && (modelo.ano == ano))	esse_sim = 1;
		if( esse_sim )
		{
			printf(
				"%03d: '%s'nascido em %02d/%02d/%04d\n", sequencia,
				modelo.nome, modelo.dia, modelo.mes, modelo.ano
			);
			sequencia += 1;
		}
	}	// while
	return sequencia - 1;
}	// xyz_filtra_uns()


int		xyz_grava_uns(FILE* file, int ano, int quantos_anos, int quantos_por_mes, int maximo)
{
	int			sequencia = 1;
	Pessoa		modelo;
	modelo.dia = 1;						// nao faz diferenca no teste

	if (file == NULL) return -1;
	for (int a = 0; a < quantos_anos; a += 1)
	{
		modelo.ano = ano + a;			// cria registros para esse ano
		for (int m = 1; m <= 12; m += 1)
		{
			modelo.mes = m;				// cria para esse mes
			for (int n = 0; n < quantos_por_mes; n += 1)
			{
				sprintf(modelo.nome, "Nome XYZ%04d", sequencia);
				printf(
					"%03d: '%s'nascido em %02d/%02d/%04d\n", sequencia,
					modelo.nome, modelo.dia, modelo.mes, modelo.ano
				);
				fwrite(&modelo, sizeof(Pessoa), 1, file);
				if (sequencia >= maximo) return 0;
				sequencia = sequencia + 1;
			}	// for n
		}	// for m
	}	// for a
	return sequencia - 1;
};	// xyz_grava_uns()

// fim do texto

 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...