Ir ao conteúdo

Posts recomendados

Postado

Olá, tenho um trabalho para desenvolver, onde encontrei a seguinte dificuldade em um problema:

 

O arquivo de saída (no formato txt) contendo o relatório separado por categoria e
sexo deve ser chamado de “inscritos.txt”;

 

Consegui fazer praticamente tudo cadastrar, alterar, exibir todos os cadastros mas essa parte de gerar relatório/arquivo setorizado não consegui alguém saberia como fazer?

 

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

//struct
typedef struct Ciclista{
    int inscricao;
    char nome[100];
    char sexo[100];
    char categoria[100];
}Ciclista;


Ciclista ciclista;


void cadastrar()
{

	FILE *arq = fopen("inscricao.txt", "a+b");
	FILE *arq2 = fopen("inscritos.txt", "a+b");


	if(arq == NULL)
	{
		printf("\nFalha ao abrir arquivo(s)!\n");
		exit(1);
	}

	Ciclista auxCiclista;


	int cont_bytes = 0;


	fseek(arq, 0, SEEK_END);

	cont_bytes = ftell(arq);

	if(cont_bytes == 0)
	{
		// se for 0, então não existe ciclista cadastrado
		// coloco a inscricao começando de 1
		auxCiclista.inscricao = 1;
	}
	else
	{

		Ciclista ultimo_ciclista;


		// pegar o último ciclista cadastrado e continuar sequencia
		fseek(arq, cont_bytes - sizeof(Ciclista), SEEK_SET);

		fread(&ultimo_ciclista, sizeof(Ciclista), 1, arq);

		auxCiclista.inscricao = ultimo_ciclista.inscricao + 1;
	}

	printf("\nDigite o nome do ciclista: ");
	scanf("%99[^\n]%*c", auxCiclista.nome);

    printf("\nDigite o sexo ciclista(Fem ou Masc): ");
	scanf("%99[^\n]%*c", auxCiclista.sexo);

	printf("\nDigite a categoria do ciclista (Sport ou Open): ");
	scanf("%99[^\n]%*c", auxCiclista.categoria);


	fseek(stdin, 0, SEEK_END);

	fseek(arq, 0, SEEK_END);

	fwrite(&auxCiclista, sizeof(Ciclista), 1, arq);

    fwrite(&auxCiclista, sizeof(Ciclista), 1, arq2);

	fclose(arq);
	fclose(arq2);



	printf("\nCiclista \"%s\" cadastrado com sucesso!\n", auxCiclista.nome);
	printf("\nPressione <Enter> para continuar...");
	scanf("%*c"); // pega o Enter e descarta

	// uma forma de "limpar" o buffer de entrada
	fseek(stdin, 0, SEEK_END);
}

void listar()
{

	FILE *arq = fopen("inscricao.txt", "rb");

	if(arq == NULL)
	{
		printf("\nFalha ao abrir arquivo ou ");
		printf("Nenhum ciclista cadastrado.\n");
		printf("\nPressione <Enter> para continuar...");
		scanf("%*c");


		fseek(stdin, 0, SEEK_END);
		return;
	}
	// variável que indica se encontrou pelo menos 1 ciclista
	int encontrou_ciclista = 0;
	printf("\nListando todos os ciclistas...\n");
	// loop para percorrer o arquivo
	Ciclista auxCiclista;
	while(1)
	{
		// fread retorna o número de elementos lidos com sucesso
		size_t result = fread(&auxCiclista, sizeof(Ciclista), 1, arq);

		// se for 0, é porque não há mais elemento, então sai do loop
		if(result == 0)
			break;

		// atualiza a variável indicando que encontrou
		// pelo menos um ciclista
		encontrou_ciclista = 1;

		// mostra os dados de cada ciclista

		printf("\nInscricao do ciclista: %d\n", auxCiclista.inscricao);
		printf("Nome do ciclista: %s\n", auxCiclista.nome);
		printf("Sexo do ciclista: %s\n", auxCiclista.sexo);
		printf("Categoria do ciclista: %s\n", auxCiclista.categoria);

	}


	if(encontrou_ciclista == 0)
		printf("\nNenhum ciclista cadastrado.\n");


	fclose(arq);

	printf("\nPressione <Enter> para continuar...");
	scanf("%*c");


	fseek(stdin, 0, SEEK_END);
}

//ALTERA alguém DO CADASTRO
void alterar(){

    //variaveis da funçao
    int contador = 0;
    int numInscricaoPesquisa = 0;

    //abre ponteiro
    FILE *ponteiro = fopen("inscricao.txt", "r+b");

    //numero inscricao de quem vai ser buscado
    system("cls");
    printf("Digite o NUMERO INSCRICAO de quem deseja alterar a categoria: ");
    scanf("%d", &numInscricaoPesquisa);
    fflush(stdin);


    if(ponteiro == NULL){
        printf("Erro ao abrir o arquivo ou não existe conteudo dentro do arquivo\n");
        system("pause");
    }
    else{
        //le a primeira linha do arquivo
        fread(&ciclista, sizeof(Ciclista), 1, ponteiro);

        //enquanto o arquivo não chegar ao final, e o Nº inscrição for diferente do registrado
        while((!feof(ponteiro) && numInscricaoPesquisa != ciclista.inscricao)) {


            //continua lendo o arquivo e soma 1 ao contador
            fread(&ciclista, sizeof(Ciclista), 1, ponteiro);
            contador++;
        }


        if(feof(ponteiro)){
            printf("\nNUMERO INSCRIÇÃO não ENCONTRADO!\n");
            system("pause");
        }


        else{


            fseek(ponteiro, contador * sizeof(Ciclista), SEEK_SET);

            printf("\nENCONTRADO...\n");
            printf("Informar a alteracao novos valores\nNUMERO INSCRICAO: %d -- CICLISTA: %s", ciclista.inscricao, ciclista.nome);

            printf("\n\nNOVA CATEGORIA: ");
            gets(ciclista.categoria);
            fflush(stdin);

            fwrite(&ciclista, sizeof(Ciclista),1,ponteiro);
            printf("\nRegistro alterado com sucesso\n\n");
            system("pause");
        }

    }


    fclose(ponteiro);
}



//menuzin
void menu(int op){
    while(op != 4) {
        system("cls");
        printf("[1] Cadastrar novo ciclista...\n");
        printf("[2] Exibir ciclistas inscritos...\n");
        printf("[3] Alterar registro...\n");
        //printf("[4] Relatorio...\n");
        printf("[4] Sair do sistema...\n");

        printf("Informe a opcao desejada...");
        scanf("%d", &op);
        fflush(stdin);

        switch(op) {
        case 1:
            cadastrar();
            break;
        case 2:
            listar();
            break;
        case 3:
            alterar();
            break;
        //case 4:
            //relatorio();
            //break;
        case 4:
            break;
        default:

            break;
        }

    }
}


int main(){

    menu(0);

    return 0;
}

 

 

  • Curtir 2
Postado
3 horas atrás, JoseC99 disse:
	FILE *arq = fopen("inscricao.txt", "a+b");
	FILE *arq2 = fopen("inscritos.txt", "a+b");

 

Use nomes mais expressivos. É melhor para você e para os outros. arq e arq2?

 

Seu programa parece muito complicado sem necessidade.

 

Se precisa saber o número do último ciclista mas ao mesmo tempo precisa copiar os caras para a memória no vetor de estruturas apenas abra o arquivo para leitura e preencha o vetor. Ao final vai saber o último basicamente porque será :) o último. Se não vai processar os ciclistas sua ideia é o a normal, por outro lado. 

 

int main(){
    menu(0);
    return 0;
}

 

Já vi isso muitas vezes, mas não é uma boa ideia menu() é menu(). Não esconda a lógica do programa dentro de uma função com esse nome. E se vai mesmo fazer isso apague menu() e ponha o código em main().

 

void x(void)

 

Isso em geral é um erro. Não use isso. Passe argumentos e retorne algo. void x(void) é um buraco negro. Nada entra, nada sai. NUNCA use globais. É um desastre. Mesmo que não pretenda trabalhar com isso.

 

3 horas atrás, JoseC99 disse:
	fseek(stdin, 0, SEEK_END);

 

seek em stdin é algo estranho. Sugiro esquecer isso.

 

3 horas atrás, JoseC99 disse:
            fflush(stdin);

            fwrite(&ciclista, sizeof(Ciclista),1,ponteiro);
            printf("\nRegistro alterado com sucesso\n\n");
            system("pause");

 

:( não use system(). É proibido em toda parte, escolas e empresas. Não vai aprender nada, não vai estar fazendo nada. system() foi escrita em C, o sistema foi provavelmente quase todo escrito em C. Use C.

 

Não use fflush() na entrada. Sequer está definido para fluxos de entrada, Geralmente indica que o programa foi mal construído e não consome a entrada corretamente.

 

3 horas atrás, JoseC99 disse:
    printf("Digite o NUMERO INSCRICAO de quem deseja alterar a categoria: ");
    scanf("%d", &numInscricaoPesquisa);

 

TESTE sempre o retorno de scanf(), em especial quando está lendo um número. Não faz sentido seguir se não ler nada. E entenda que o que vier depois do último dígito vai ficar lá para ser lido.

 

3 horas atrás, JoseC99 disse:
           gets(ciclista.categoria);
 

 

NUNCA use gets(). Seu compilador certamente avisou sobre isso. Essa função é uma bobagem antiga. Use fgets().

 

Sobre essa construção...

 

void menu(int op){
    while(op != 4) {
        system("cls");
        printf("[1] Cadastrar novo ciclista...\n");
        printf("[2] Exibir ciclistas inscritos...\n");
        printf("[3] Alterar registro...\n");
        //printf("[4] Relatorio...\n");
        printf("[4] Sair do sistema...\n");

        printf("Informe a opcao desejada...");
        scanf("%d", &op);
        fflush(stdin);

        switch(op) {
 
            // ...
            
            //case 4:
            //relatorio();
            //break;
        case 4:
            break;
        default:

            break;
        }

    }
}

 

Qual o propósito? Para que passa um argumento para o menu ao invés de retornar?

 

Qual seria o sentido de alguém chamar menu(4) por exemplo? Perder uns milisegundos?

 

E como pode não retornar nada?

 

Era isso que pretendia?

 

int menu()
{
	int op = 0;
    while(op != 4)
    {
        system("cls");
        printf("[1] Cadastrar novo ciclista...\n");
        printf("[2] Exibir ciclistas inscritos...\n");
        printf("[3] Alterar registro...\n");
        //printf("[4] Relatorio...\n");
        printf("[4] Sair do sistema...\n");

        printf("Informe a opcao desejada...");
        scanf("%d", &op);
        fflush(stdin);

        switch(op) {
        case 1:
            cadastrar();
            break;
        case 2:
            listar();
            break;
        case 3:
            alterar();
            break;
        //case 4:
            //relatorio();
            //break;
        case 4:
            break;
        default:

            break;
        }

    }
  	return op;
}

 

Ainda sobre menu()

 

        system("cls");
        printf("[1] Cadastrar novo ciclista...\n");
        printf("[2] Exibir ciclistas inscritos...\n");
        printf("[3] Alterar registro...\n");
        //printf("[4] Relatorio...\n");
        printf("[4] Sair do sistema...\n");

        printf("Informe a opcao desejada...");
        scanf("%d", &op);
        fflush(stdin);

 

Como eu disse, evite system(), em geral proibida. E esqueça fflush() para a entrada porque sequer está definido em todas plataformas. E TESTE o retorno de scanf() sempre.

 

E esses printf() não são nada eficientes... Prefira o simples e mais legível:

 

        printf("\
    [1] Cadastrar novo ciclista...\n\
    [2] Exibir ciclistas inscritos...\n\
    [3] Alterar registro...\n\
    [4] Relatorio...\n\
    [5] Sair do sistema...\n\
\n\
    Informe a opcao desejada: ");

 

Uma única chamada de função, vai levar muitas vezes menos tempo. E é muito mais fácil de ler e de editar.

 

 

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 comunidades 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...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!