• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Guest tsenart

Gestao Biblioteca

9 mensagens neste tópico

Ola pessoal.

Estive a escrever este código(que e a resolução de um exercicio) mas emperrei nesta função que na execução do programa me dá segmentation fault.

Ainda tenho de implementar a escrita da informação para ficheiros... Quando estiver terminado ponho isto no armazem de código.

/*Programa desenvolvido por S@m0t*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio2.h>

#define MAX_LIVROS 200

typedef struct
{
        int dia;
        int mes;
        int ano;
} DATA_M;

typedef struct
{
        char cota[20];
        char autor[40];
        char titulo[60];
        DATA_M data_aquisicao;
        char estado;
} LIVRO;

typedef struct
{
        LIVRO livro[MAX_LIVROS];
        unsigned int conta;
} BIBLIOTECA;


void cls()
{
     fflush(stdin);
     getch();
     clrscr();
}

void inic(BIBLIOTECA *ptr)
{
  int i;
     
     ptr->conta=0;
     for(i=0;i<=MAX_LIVROS;i++)
     {
         strcpy(ptr->livro[i].cota, "NULL");    /*Porque e que aqui nao posso simplesmente fazer     ptr->livro[i].cota = "NULL";   ? o mesmo para os outros  */
         strcpy(ptr->livro[i].autor, "NULL");
         strcpy(ptr->livro[i].titulo, "NULL");
         ptr->livro[i].data_aquisicao.dia = 0;
         ptr->livro[i].data_aquisicao.mes = 0;
         ptr->livro[i].data_aquisicao.ano = 0;
         ptr->livro[i].estado = '0';
     }
}

void apresenta_menu()
{
     printf("\n\t\t\tGestao de uma biblioteca\n");
     printf("\t\t1 - Introduzir um novo livro\n");
     printf("\t\t2 - Alterar o estado de um livro\n");
     printf("\t\t3 - Listar os livros requesitados\n");
     printf("\t\t4 - Listar os livros ordenados pela cota\n");
     printf("\t\t5 - Listar os livros ordenados pelo autor\n");
     printf("\t\t6 - Terminar o programa\n");
}

void introduzir_livro(BIBLIOTECA *ptr)
{
     printf("Cota: "); gets(ptr->livro[ptr->conta].cota);   /* E aqui que ele encrava.....*/
     printf("Autor: "); gets(ptr->livro[ptr->conta].autor);
     printf("Titulo: "); gets(ptr->livro[ptr->conta].titulo);
     printf("Data de aquisicao(dd/mm/aaaa): "); scanf("%d/%d/%d",&ptr->livro[ptr->conta].data_aquisicao.dia, &ptr->livro[ptr->conta].data_aquisicao.mes, &ptr->livro[ptr->conta].data_aquisicao.ano);
     ptr->livro[ptr->conta].estado='L';
     ptr->conta++;
}

void alterar_estado(BIBLIOTECA *ptr)
{
char tmp_estado, tmp_cota[20];
int i;
     
     printf("Qual a cota do livro? "); gets(tmp_cota);
     for(i=0;i<=MAX_LIVROS;i++);
     {
         if(strcmp(ptr->livro[i].cota, tmp_cota)==0)
         {
             printf("Novo estado(L - Livre, R - Requesitado, C - Acesso Condicionado): "); tmp_estado = getchar();
             if(toupper(tmp_estado) != 'L' && toupper(tmp_estado) != 'R' && toupper(tmp_estado) != 'C')
             {
                 printf("Estado invalido\n"); return;
             }
             ptr->livro[i].estado = toupper(tmp_estado);
         }
     }
}


void listar_req(BIBLIOTECA bib)
{
int i;
    
    for(i=0;i<=MAX_LIVROS; i++)
    {
            if(bib.livro[i].estado=='R')
            {
                puts(bib.livro[i].cota);
                puts(bib.livro[i].autor);
                puts(bib.livro[i].titulo);
                printf("%d/%d/%d\n",bib.livro[i].data_aquisicao.dia, bib.livro[i].data_aquisicao.mes, bib.livro[i].data_aquisicao.ano);
                switch(toupper(bib.livro[i].estado))
                {
                    case 'L': puts("LIVRE"); break;
                    
                    case 'R': puts("REQUESITADO"); break;
                    
                    case 'C': puts("ACESSO CONDICIONADO"); break;
                    
                    default: puts("?");
                    
                }
            }
    }
}


int listar_cota(BIBLIOTECA bib)
{
char tmp_cota[20];
int i;
     
     printf("Qual a cota do livro a procurar? "); gets(tmp_cota);
     for(i=0;i<=MAX_LIVROS;i++);
     {
         if(strcmp(bib.livro[i].cota, tmp_cota)==0)
         {
                puts(bib.livro[i].cota);
                puts(bib.livro[i].autor);
                puts(bib.livro[i].titulo);
                printf("%d/%d/%d\n",bib.livro[i].data_aquisicao.dia, bib.livro[i].data_aquisicao.mes, bib.livro[i].data_aquisicao.ano);
                switch(toupper(bib.livro[i].estado))
                {
                    case 'L': puts("LIVRE\n"); break;
                    
                    case 'R': puts("REQUESITADO\n"); break;
                    
                    case 'C': puts("ACESSO CONDICIONADO\n"); break;
                    
                    default: puts("?");
                }
                return i;
         }
     }
return 0;
}


void listar_autor(BIBLIOTECA bib)
{
  int i;
  char tmp_autor[40];
      
      printf("Qual o nome do autor do livro a procurar? "); gets(tmp_autor);
      for(i=0;i<=MAX_LIVROS;i++)
      {
          if(strcmp(bib.livro[i].autor, tmp_autor)==0)
          {
                puts(bib.livro[i].cota);
                puts(bib.livro[i].autor);
                puts(bib.livro[i].titulo);
                printf("%d/%d/%d\n",bib.livro[i].data_aquisicao.dia, bib.livro[i].data_aquisicao.mes, bib.livro[i].data_aquisicao.ano);
                switch(toupper(bib.livro[i].estado))
                {
                    case 'L': puts("LIVRE\n"); break;
                    
                    case 'R': puts("REQUESITADO\n"); break;
                    
                    case 'C': puts("ACESSO CONDICIONADO\n"); break;
                    
                    default: puts("?");
                }
          }
      }
}
             


int main()
{
  int opcao;

    BIBLIOTECA biblioteca;
    inic(&biblioteca);
    while(1)
    {
        apresenta_menu(); printf("\nOpcao-> "); scanf("%d", &opcao); cls();
        
        switch(opcao)
        {
            case 1: introduzir_livro(&biblioteca); cls(); break;
            
            case 2: alterar_estado(&biblioteca); cls(); break;
            
            case 3: listar_req(biblioteca); cls(); break;
            
            case 4: listar_cota(biblioteca); cls(); break;
            
            case 5: listar_autor(biblioteca); cls(); break;
            
            case 6: exit(0);
            
            default: printf("\nOpcao invalida\n"); cls();
        }
    }
return 0;
}
    

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Era bom saber onde dá o SEGMENTATION FAULT, por função de execução do programa entendo por muitas coisas, aliás é todas as funções. ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

por que razão usar está a usar um 'exit' para sair do programa?

devias evitar o uso da biblioteca 'conio2'.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

pah acho que sei o que é.... Não te esquecas que as strings k tens na estrutura LIVRO não são apontadores para uma determinada posição de memoria( char* cota) ou (void * cota). A função getc recebe como parametro um char *, e a forma como ela lê o input do stdin implica troca de apontadores, como tu estas a mandar um vector de caracteres,vai dar segmentation fault. Usa o scanf("%[^\n]"), que penso que faz o k precisas. NÃO há problema nenhum em utilizares a função exit(). O processo que corre o teu programa, vai terminar com um exit(0) após sair do main  ;),.... mas realmente não era necessario ai.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

NÃO há problema nenhum em utilizares a função exit(). O processo que corre o teu programa, vai terminar com um exit(0) após sair do main  ;),.... mas realmente não era necessario ai.

problema não há, assim como não há problemas em não modularizar os programas ou usar 'goto', desde que o programa funcione... mas há alternativa mais correctas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

NÃO há problema nenhum em utilizares a função exit(). O processo que corre o teu programa, vai terminar com um exit(0) após sair do main  ;),.... mas realmente não era necessario ai.

problema não há, assim como não há problemas em não modularizar os programas ou usar 'goto', desde que o programa funcione... mas há alternativa mais correctas.

Não é uma comparação que se faça...um goto é má programação...O exit é necessario, se estiveres a trabalhar com processos no mesmo programa tens obrigatóriamente que usar o exit. Mas sim, neste caso concordo contigo, que fica mal.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu costumo usar o exit(), mas realmente aí podias por um ciclo que rolasse enquanto não fosse digitado 6.

//codigo...

do{

   //codigo...

}while(opcao != 6);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu costumo usar o exit(), mas realmente aí podias por um ciclo que rolasse enquanto não fosse digitado 6.

eu também costumo usar o 'exit', normalmente em funções que não a 'main' (a não ser em situações de erro), pois na 'main' um 'return' também termina o programa.

neste caso bastava substituir o 'exit' por um 'return'. se bem que, na minha opinião, a melhor solução era por o 'while' a verificar o valor da opção (tal como o Hipnoted sugeriu) pois não gosto de usar 'while(1)'.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora