Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Jean Martins

Problemas com Struct e Arquivos

Recommended Posts

Ola pessoal!

 

Preciso fazer um trabalho da facul e é o seguinte:

 

 

Implementar um programa para auxiliar no fechamento das notas do semestre

Sabendo que o usuário deve entrar com a quantidade de disciplina, o numero

de avaliações por disciplina e o peso das mesmas quando for o caso.

O programa deve armazenar o código do aluno, nome, periodo, disciplinas e a média

em cada uma delas.

Apresente as seguintes opções:

1-Cadastrar Aluno

2-Cadastrar Disciplina

3-Lançar Notas

4-Consulta Aluno

 

obs: Armazena os dados em 2 arquivos um para disciplinas e outro para alunos.

 

Utilize 2 tipos de ED para pesquisar, listas encadeada dinamica e arvore binária

de busca

 

Estou usando lista encadeada para isnerir os dados.Uma de minhas duvida é na struct, como irei cadastrar o campo disciplina dentro da struct aluno, sendo que irei cadastrar as disciplinas e depois os alunos? A funcao de leitura no arquivo nao esta funcionando. Segue o codigo:

 

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


typedef struct aluno   // estrutura da ficha de aluno
{
   int codigo;
   char nome[30];
   char periodo[30];
   struct disciplina* disciplina;
   float media;
   struct aluno* prox;
}tAluno;

typedef struct disciplina   // estrutura de ficha para disciplina
{
   int codigo;
   char nomeDisciplina[30];
   int numProva;
   struct disciplina* prox;
}tDisciplina;

/*
****************** Escopo de funções   ***************************/
int menu();
void cadAluno(tAluno** p, tAluno** u);
void cadDisciplina(tDisciplina** p, tDisciplina** u);
void salvaDisciplina(tDisciplina* p);
void leDisciplina(tDisciplina* p);

/* **************************************************************/

int main()
{
   tAluno* p; tAluno* u;
   p = NULL; u = NULL;

   tDisciplina *p1; tDisciplina *u1;
   p1 = NULL; u1 = NULL;

   int opcao;

   do
   {

       opcao = menu();

       switch(opcao)
       {
           case 1:
                   printf("\n\nCadastro de Alunos\n\n");

                   cadAluno(&p,&u);

                   break;
           case 2:
                   printf("\n\nCadastro de Disciplinas\n\n");

                   cadDisciplina(&p1,&u1);
                   salvaDisciplina(p1);

                   break;
           case 3:
                   printf("\n\nLancamento de Notas\n\n");

// falta implementar, mas estou usando como teste para ler o arquivo, posteriormente irei fazer uma busca e mostrar os dados em uma arvore binaria.

                       leDisciplina(p1);

                   break;
            case 4:
                   printf("\n\nConsulta de Alunos\n\n");

                   break;
           default:
                   printf("\n\nNenhuma opcao selecionada\n\n");
                   break;

       }
   }
   while(opcao!= 4);
   system ( "Pause" );
   return 0;
}

int menu()
{
   int opcao;

   printf("::::::::::::::::: SysMedia Ver.beta1.0 ::::::::::::::::::::::");
   printf("\n\n\nMenu Principal\n\n");
   printf("\n 1 - Cadastrar Alunos");
   printf("\n 2 - Cadastrar Disciplinas ");
   printf("\n 3 - Lancar Notas");
   printf("\n 4 - Consultar Aluno");
   printf("\n\n\nEscolha sua opcao:");
   scanf("%d",&opcao);
   return opcao;
}


void cadAluno(tAluno** p, tAluno** u)
{
    tAluno* novo;

   novo = (tAluno*)malloc(sizeof(tAluno));

   printf("Codigo:");
   scanf("%d",&novo->codigo);
   fflush(stdin);
   printf("Nome:");
   scanf("%s", novo->nome);
   fflush(stdin);
   printf("Periodo:");
   scanf("%s", novo->periodo);
   fflush(stdin);
   printf("Disciplina:");
   scanf("%s", novo->disciplina->nomeDisciplina); // preciso puxar a disciplina cadastrada
   fflush(stdin);
   printf("Media:");
   scanf("%f", &novo->media);

   novo->prox = NULL;
   if(*u == NULL)
   {
      *p = novo;
      *u = novo;
   }
   else
   {
       (*u)->prox = novo;
       *u = novo;
   }
}

void cadDisciplina(tDisciplina** p, tDisciplina** u)
{
    tDisciplina* nova; FILE* arq;

   nova = (tDisciplina*)malloc(sizeof(tDisciplina));

   printf("Codigo:");
   scanf("%d",&nova->codigo);
   fflush(stdin);
   printf("Nome da Disciplina:");
   scanf("%s", nova->nomeDisciplina);
   fflush(stdin);
   printf("Quantidade de Provas:");
   scanf("%d", &nova->numProva);

   nova->prox = NULL;
   if(*u == NULL)
   {
      *p = nova;
      *u = nova;
   }
   else
   {
       (*u)->prox = nova;
       *u = nova;
   }
}

void salvaDisciplina(tDisciplina* p)
{
   FILE* arq;
   arq = fopen("disciplinas.jma","wb");
   fwrite(&p,sizeof(tDisciplina),1,arq);
   fclose(arq);
}

/*
************   teste para leitura no arquivo   ***********************
*/
void leDisciplina(tDisciplina* p)
{

   FILE* arq;

   arq = fopen("disciplinas.jma","rb");
   if(arq == NULL)
   {
       printf("nao abriu");
   }
   fseek(p,0,SEEK_SET);
  fread(&p, sizeof(tDisciplina),1,arq);

       printf("\ncodigo: %d", p->codigo);
       printf("\nnome Disciplina: %s", p->nomeDisciplina);
       printf("\nQtde de Provas: %d", p->numProva);

  fclose(arq);
}





Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguns conselhos gerais:

 

0. Não passe stdin para fflush.

 

1. Não faça casting de (void *) para outro tipo de ponteiro para objeto. malloc retorna um valor de tipo (void *). O melhor a fazer é algo como:

 

T *a = NULL;

a = malloc(sizeof *a);
// No seu caso, por exemplo: novo = malloc(sizeof *novo);

 

2. É possível e encorajado inicializar variáveis no momento da declaração:

 

int    a     = 10;
tAluno *novo = malloc(sizeof *novo);

 

3. As funções de leitura e escrita estão passando valores do tipo errado como primeiro argumento. Você está passando ponteiros para ponteiros. Sugiro que leia http://guipn.com/cpa.htm para aprender mais sobre vetores e ponteiros.

 

4. A chamada a fseek em lerDisciplina é desnecessária.

 

5. Prefira designar tipos de ponteiro mantendo o asterisco encostado no nome do identificador sendo declarado: int *p ao invés de int* p. Isto evita confusão em linhas como a seguinte:

 

int* a, b, c;

 

Acima, apenas 'a' é um ponteiro. O asterisco encostado em 'int' dificulta a leitura.

 

6. Procure detalhar ao máximo possível as declarações de funções quanto à lista de parâmetros:

 

int menu(void); // vs. int menu()

 

Acima, a declaração comentada declara uma função retornando (int) e de nome 'menu', e não inclui informações de parametrização. Isto permite que a função seja definida com parâmetros. Se a definição da função mudar para outro arquivo, vai ficar mais difícil saber o que a função de fato faz (veja http://codepad.org/m7apoTDS).

 

Aplique esta prática à main. Defina-a assim:

 

int main(void) { /* ... */ }

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguns conselhos gerais:

 

0. Não passe stdin para fflush.

 

1. Não faça casting de (void *) para outro tipo de ponteiro para objeto. malloc retorna um valor de tipo (void *). O melhor a fazer é algo como:

 

T *a = NULL;

a = malloc(sizeof *a);
// No seu caso, por exemplo: novo = malloc(sizeof *novo);

 

2. É possível e encorajado inicializar variáveis no momento da declaração:

 

int    a     = 10;
tAluno *novo = malloc(sizeof *novo);

 

3. As funções de leitura e escrita estão passando valores do tipo errado como primeiro argumento. Você está passando ponteiros para ponteiros. Sugiro que leia http://guipn.com/cpa.htm para aprender mais sobre vetores e ponteiros.

 

4. A chamada a fseek em lerDisciplina é desnecessária.

 

5. Prefira designar tipos de ponteiro mantendo o asterisco encostado no nome do identificador sendo declarado: int *p ao invés de int* p. Isto evita confusão em linhas como a seguinte:

 

int* a, b, c;

 

Acima, apenas 'a' é um ponteiro. O asterisco encostado em 'int' dificulta a leitura.

 

6. Procure detalhar ao máximo possível as declarações de funções quanto à lista de parâmetros:

 

int menu(void); // vs. int menu()

 

Acima, a declaração comentada declara uma função retornando (int) e de nome 'menu', e não inclui informações de parametrização. Isto permite que a função seja definida com parâmetros. Se a definição da função mudar para outro arquivo, vai ficar mais difícil saber o que a função de fato faz (veja http://codepad.org/m7apoTDS).

 

Aplique esta prática à main. Defina-a assim:

 

int main(void) { /* ... */ }

 

Olá, dei uma lida nos seus artigos, aprendi um pouco mais, coisas que eu nem sabia até entao, ai fiz algumas alterações no codigo, porem ainda sigo com minhas duvidas sobre a struct e a função fread e fwrite, me confundi um pouco pois vi diversos conteudos e alguns são bastante diferentes um do outro, segue abaixo o codigo:

 

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


typedef struct aluno   // estrutura da ficha de aluno
{
   int codigo;
   char nome[30];
   char periodo[30];
   struct disciplina *disciplina;
   float media;
   struct aluno *prox;
}tAluno;

typedef struct disciplina   // estrutura de ficha para disciplina
{
   int codigo;
   char nomeDisciplina[30];
   int numProva;
   struct disciplina *prox;
}tDisciplina;

/*
****************** Escopo de funções   ***************************/
int menu(void);
void cadAluno(tAluno **primeiro, tAluno **ultimo);
void cadDisciplina(tDisciplina **primeiro1, tDisciplina **ultimo1);
void salvaDisciplina(tDisciplina *primeiro1);
void leDisciplina(tDisciplina *primeiro1);

/* **************************************************************/

int main(void)
{
   tAluno *primeiro, *ultimo;
   primeiro, ultimo = NULL;

   tDisciplina *primeiro1, *ultimo1;
   primeiro1, ultimo1 = NULL;

   int opcao;

   do
   {

       opcao = menu();

       switch(opcao)
       {
           case 1:
                   printf("\n\nCadastro de Alunos\n\n");

                   cadAluno(&primeiro,&ultimo);

                   break;
           case 2:
                   printf("\n\nCadastro de Disciplinas\n\n");

                   cadDisciplina(&primeiro1,&ultimo1);
                   break;
           case 3:
                   printf("\n\nLancamento de Notas\n\n");
                       leDisciplina(primeiro1);
                   break;
            case 4:
                   printf("\n\nConsulta de Alunos\n\n");

                   break;
           default:
                   printf("\n\nNenhuma opcao selecionada\n\n");
                   break;

       }
   }
   while(opcao!= 4);
   system ( "Pause" );
   return 0;
}

int menu(void)
{
   int opcao;

   printf("::::::::::::::::: SysMedia Ver.beta1.0 ::::::::::::::::::::::");
   printf("\n\n\nMenu Principal\n\n");
   printf("\n 1 - Cadastrar Alunos");
   printf("\n 2 - Cadastrar Disciplinas ");
   printf("\n 3 - Lancar Notas");
   printf("\n 4 - Consultar Aluno");
   printf("\n\n\nEscolha sua opcao:");
   scanf("%d",&opcao);
   return opcao;
}

void cadAluno(tAluno **primeiro, tAluno **ultimo)
{
   tAluno *novoAluno = malloc(sizeof *novoAluno);

   printf("Codigo:");
   scanf("%d",&novoAluno->codigo);
   printf("Nome:");
   scanf("%s", novoAluno->nome);
   printf("Periodo:");
   scanf("%s", novoAluno->periodo);
   printf("Disciplina:");
   scanf("%s", novoAluno->disciplina->nomeDisciplina);
   printf("Media:");
   scanf("%f", &novoAluno->media);

   novoAluno->prox = NULL;
   if(*ultimo == NULL)
   {
      *primeiro = novoAluno;
      *ultimo = novoAluno;
   }
   else
   {
       (*ultimo)->prox = novoAluno;
       *ultimo = novoAluno;
   }
}

void cadDisciplina(tDisciplina **primeiro1, tDisciplina **ultimo1)
{
  tDisciplina *novaDisciplina = malloc(sizeof *novaDisciplina);

   printf("Codigo:");
   scanf("%d",&novaDisciplina->codigo);
   printf("Nome da Disciplina:");
   scanf("%s", novaDisciplina->nomeDisciplina);
   printf("Quantidade de Provas:");
   scanf("%d", &novaDisciplina->numProva);

   novaDisciplina->prox = NULL;
   if(*ultimo1 == NULL)
   {
      *primeiro1 = novaDisciplina;
      *ultimo1 = novaDisciplina;
   }
   else
   {
       (*ultimo1)->prox = novaDisciplina;
       *ultimo1 = novaDisciplina;
   }
   salvaDisciplina(novaDisciplina);
}

void salvaDisciplina(tDisciplina *primeiro1)
{
   FILE *arq = fopen("disciplinas.jma","wb");
   fwrite(&primeiro1,sizeof(tDisciplina),1,arq);// aqui passo o endereço do
//primeiro dado de minha lista simples?
   fclose(arq);
}

/*
************   teste para leitura no arquivo   ***********************
*/
void leDisciplina(tDisciplina* primeiro1)
{

   FILE *arq = fopen("disciplinas.jma","rb");
   if(arq == NULL)
   {
       printf("nao abriu");
   }

  fread(&primeiro1, sizeof(tDisciplina),1,arq);  // aqui passo o endereço do
//primeiro dado de minha lista simples?

       printf("\ncodigo: %d", primeiro1->codigo);
       printf("\nnome Disciplina: %s", primeiro1->nomeDisciplina);
       printf("\nQtde de Provas: %d", primeiro1->numProva);

  fclose(arq);
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

olá! Dei uma mexida no codigo e tive a ideia de cadastrar as disciplinas no arquivo e depois mostrá-la em uma lista encadeada, mas está acontecendo o seguinte, quando entro no programa pra cadastrar a disciplina ele cadastra certo e peço pra ler do arquivo e mostrar na tela beleza. Mas se eu entro no programa e peço somente pra mostrar as disciplinas cadastradas o programa dá erro. Alguem pode me ajudar? será que o problema está no ponteiro que está passando para a leDisciplina?

 

typedef struct disciplina   // estrutura de ficha para disciplina
{
   int codigo;
   char nomeDisciplina[30];
   int numProva;
}tDisciplina;

/*
****************** Escopo de funções   ***************************/
int menu(void);
//void cadAluno(tAluno **primeiro, tAluno **ultimo);
void cadDisciplina(tDisciplina **disciplina);
void salvaDisciplina(tDisciplina *disciplina);
void leDisciplina(tDisciplina *disciplina);

/* **************************************************************/



int main(void)
{

   tDisciplina *disciplina = NULL;

   int opcao;

   do
   {

       opcao = menu();

       switch(opcao)
       {
           case 1:
                   printf("\n\nCadastro de Alunos\n\n");

                   break;
           case 2:
                   printf("\n\nCadastro de Disciplinas\n\n");

                   cadDisciplina(&disciplina);
                   break;
           case 3:
                   printf("\n\nDisciplinas Cadastradas\n\n");
                       leDisciplina(disciplina);
                   break;
            case 4:
                   printf("\n\nConsulta de Alunos\n\n");

                   break;
           default:
                   printf("\n\nNenhuma opcao selecionada\n\n");
                   break;

       }
   }
   while(opcao!= 4);
   system ( "Pause" );
   return 0;
}

int menu(void)
{
   int opcao;

   printf("::::::::::::::::: SysMedia Ver.beta1.0 ::::::::::::::::::::::");
   printf("\n\n\nMenu Principal\n\n");
   printf("\n 1 - Cadastrar Alunos");
   printf("\n 2 - Cadastrar Disciplinas ");
   printf("\n 3 - Lancar Notas");
   printf("\n 4 - Consultar Aluno");
   printf("\n\n\nEscolha sua opcao:");
   scanf("%d",&opcao);
   return opcao;
}

void cadDisciplina(tDisciplina **disciplina)
{

  tDisciplina *novaDisciplina = malloc(sizeof *novaDisciplina);

   printf("Codigo:");
   scanf("%d",&novaDisciplina->codigo);
   printf("Nome da Disciplina:");
   scanf("%s", novaDisciplina->nomeDisciplina);
   printf("Quantidade de Provas:");
   scanf("%d", &novaDisciplina->numProva);

   salvaDisciplina(novaDisciplina);
}

void salvaDisciplina(tDisciplina *disciplina)
{
   FILE *arq = fopen("disciplinas.jma","wb");
   fwrite(&disciplina,sizeof(tDisciplina),1,arq);
   fclose(arq);
}

/*
************   teste para leitura no arquivo   ***********************
*/
void leDisciplina(tDisciplina *disciplina)
{

   FILE *arq = fopen("disciplinas.jma","rb");
   if(arq == NULL)
   {
       printf("nao abriu");
   }

  while(!feof(arq))
   {
       fread(&disciplina,sizeof(tDisciplina),1,arq);

       printf("\ncodigo: %d", disciplina->codigo);
       printf("\nnome Disciplina: %s", disciplina->nomeDisciplina);
       printf("\nQtde de Provas: %d", disciplina->numProva);
   }
  fclose(arq);
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.