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

Sign in to follow this  
metaclay

Gestão de músicas

Recommended Posts

metaclay

Boa noite a todos.

Estou com um problemazinho num projecto meu. O que estou a fazer é um programa que sirva como base de dados de Musicas. A minha dúvida é a seguinte: Já fiz uma função em que lê os dados para um vector e também já fiz a função para a escrita dos dados. Só que quando executo o programa, este não está a mostrar os dados correctamente. Deixo-vos com uma parte do programa para analisarem e dizerem-me os erros :)

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

typedef struct {
        
        int seg;
        int min;
        int hora;
        } TEMPO;
        
typedef struct {
        
        char nome[50];
        char artista [50];
        char album [50];
        int tipo;
        TEMPO duracao;
        long int bytes;
        } MUSICA;

void fmenu()
{


int escolha=1;


printf("\n ");
      printf("\t\t************************************************ \n");
      printf("\t\t************************************************ \n");
      printf("\t\t***************** TP MUSIC ********************* \n");
      printf("\t\t************************************************ \n");
      printf("\t\t************************************************ \n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t****** \t 1 - Ler dados             \t  ******\n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t****** \t 2 - Mostrar dados                ******\n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t****** \t 3 - Ordenar por tipo de musica   ******\n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t****** \t 4 - Ordenar por nome             ******\n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t****** \t 5 - Sair         \t\t  ******\n");
      printf("\t\t******\t                                  ******\n");
      printf("\t\t************************************************ \n");
      printf("\t\t************************************************ \n");
      printf("\t\t************************************************ \n");
      printf("\t\t************************************************ \n");




}

void fler(MUSICA v[50])
{
                           
                           int i;
                           for(i=0;i<2;i++)
                           {
                           printf("MUSICA [%d]",i+1);                
                           printf("\nInsira o Nome: ");
                           gets(v[i].nome);
                           fflush(stdin);
                           printf("\nInsira o Artista: ");
                           gets(v[i].artista);
                           fflush(stdin);
                           printf("\nInsira o Album: ");   
                           gets(v[i].album);
                           fflush(stdin);
                           printf("\nInsira o Tipo de musica: ");
                           scanf("%d", &v[i].tipo);
                           fflush(stdin);
                           printf("\nInsira o numero de segundos: ");
                           scanf("%d", &v[i].duracao.seg);
                           fflush(stdin);
                           printf("\nInsira o numero de minutos: ");
                           scanf("%d", &v[i].duracao.min);   
                           fflush(stdin);  
                           printf("\nInsira o numero de horas: ");
                           scanf("%d", &v[i].duracao.hora);
                           fflush(stdin);
                           printf("\nInsira o numero de Bytes: ");
                           fflush(stdin);
                           scanf("%ld", &v[i].bytes);
                           fflush(stdin);
                           system("cls");
                           }
                           
}

void fescrita (MUSICA v[50])
{
                         
                         int i;
                         for (i=0;i<2;i++)
                         {
                         printf("MUSICA [%d]",i+1);               
                         printf("\nNome da Musica: %s", v[i].nome);
                         printf("\nNome do Artista: %s", v[i].artista);
                         printf("\nNome do Album: %s", v[i].album);
                         printf("\nTipo de musica: %d", v[i].tipo);
                         printf("\nDuracao da musica: %d/%d/%d", v[i].duracao.hora, v[i].duracao.min, v[i].duracao.seg);
                         printf("\nNumero de bytes: %d", v[i].bytes);
                         getchar();
                         system("cls");
                         }
                         
}

       
     
     
     
main ()

{
     int op,i;
     MUSICA v[50]; 
     fmenu();
     printf("\nInsira a sua opccao:\n");
     scanf ("%d",&op);
     fflush(stdin);
     system("cls"); 
     
     switch (op)
      {
             case 1: {     
                           fler(v);
                           
                           main ();
                           break;
                           system("cls");
                     }

          case 2:
                     {   
                         
                         fescrita(v);
                         
                         main ();
                         break;
                         system("cls");                        
                           }
     
     
     }
     getchar();
     getchar();
     
     
     }

Share this post


Link to post
Share on other sites
pmg

Tu chamas a função main() recursivamente.

De cada vez que ela é chamada, o compilador cria as variáveis lá definidas (op, i, v[]) novamente a branco, por isso é que "ele não mostra os dados". Os dados não existem -- ou melhor existem ... mas é na função main() anterior.

Vê lá se consegues fazer o programa funcionar sem recursividade,

PS

a) NUNCA USES gets()

:) deves testar sempre o resultado de scanf()

c) fflush(stdin) não funciona em todos os compiladores

d) para imprimir um long int, o formato próprio para o printf() é "%ld" (printf("Numero de bytes"))


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
pmg
NUNCA USES gets()

Podias dizer o motivo.

Ya, sorry.

Não é possível limitar o gets() a receber um determinado número de bytes.

Um utilizador mal intencionado (ou apenas brincalhão) pode causar buffer overflows facilmente.

Imagina que eu tenho um programa que pede ao utilizador o nome.

#include <stdio.h>
/* ... */
char nome[50];
fgets(nome, 50, stdin);

Se o utilizador escrever um nome com 50 caracteres ou mais, esses caracteres extra ficam no buffer de input à espera da leitura seguinte.

Com o gets ... esses caracteres extra são copiados para as posições de memória a seguir ao nome sem controle nenhum... e sabe-se lá o que isso pode causar.

Links:

http://www.c-faq.com/stdio/getsvsfgets.html

http://msdn.microsoft.com/en-us/library/2029ea5f.aspx

http://en.wikipedia.org/wiki/Gets

http://en.wikipedia.org/wiki/Morris_worm

The Morris worm exploited an overflow vulnerability in fingerd (among others) to spread.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
metaclay

Tu chamas a função main() recursivamente.

De cada vez que ela é chamada, o compilador cria as variáveis lá definidas (op, i, v[]) novamente a branco, por isso é que "ele não mostra os dados". Os dados não existem -- ou melhor existem ... mas é na função main() anterior.

Vê lá se consegues fazer o programa funcionar sem recursividade,

PS

a) NUNCA USES gets()

:) deves testar sempre o resultado de scanf()

c) fflush(stdin) não funciona em todos os compiladores

d) para imprimir um long int, o formato próprio para o printf() é "%ld" (printf("Numero de bytes"))

Então diz-me uma maneira de voltar ao menu depois de um case sem usar o main() repetidamente pf

Share this post


Link to post
Share on other sites
pmg
/* ... #includes, definição de funções, ... */
int main(void) {
  /* ... variáveis locais ... */
  for (; {
    op = menu();
    if (op == 5) break; /* sai do for(; */
    switch (op) {
      case '1': whatever(); break; /* sai do switch() */
      /* ... */
      default: whatever(); break; /* sai do switch() */
    }
  }
  return 0;
}


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
TheDark

Também tens linhas de código após os breaks do switch:

             case 1: {     
                           fler(v);
                           
                           main ();
                           break;
                           system("cls");
                     }

Ali o system("cls"); nunca irá ser executado.


Desaparecido.

Share this post


Link to post
Share on other sites
pmg

A respeito do gets() experimenta este programeta.

#include <stdio.h>

struct Control {
  char name[4];
  char n;
};

int main(void) {
  struct Control x;
  x.n = 0;
  while (x.n++ < 4) {
    printf("Loop %d\nIntroduz nome (max 3 caracteres)\n", x.n);
    gets(x.name);
    printf("Loop %d acabado.\nO nome lido foi: %s\n\n", x.n, x.name);
  }
  puts("Programa terminado.");
  return 0;
}

Ele deve correr o ciclo 4 vezes.

Na primeira vez mete um nome com 3 letras;

na segunda vez mete um nome com 4 letras;

na terceira vez mete um nome com 5 letras;

hehehehe e na última vez mete um nome com 6 letras :)

Agora substitui o gets por fgets(x.name, 4, stdin); e corre-o outra vez.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
metaclay

Vocês estão a dar respostar que não têm nada a ver com o que quero. :|

Só quero que me digam como corrijo o programa de maneira a mostrar os dados lidos no vector, noutra função. :)

Share this post


Link to post
Share on other sites
pmg
Vocês estão a dar respostar que não têm nada a ver com o que quero.

Desculpa estar a abusar do teu "post" :)

Mas já te dei a maneira de mostrar os dados lidos numa mensagem anterior.

É preciso desenvolver a resposta mais, talvez integrando-a com o teu código?


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
metaclay

Desculpa estar a abusar do teu "post" :)

Mas já te dei a maneira de mostrar os dados lidos numa mensagem anterior.

É preciso desenvolver a resposta mais, talvez integrando-a com o teu código?

Desculpa, é que não entendi como isso pode resolver o meu problema :$

Se não te importas, formula a resposta com código completo. :)

Share this post


Link to post
Share on other sites
TheDark

Se não te importas, formula a resposta com código completo. :)

A comunidade está aqui para tentar ajudar-te com as dúvidas que tenhas, dando exemplos que ajudem a resolver problemas. Pedir "código completo" não se enquadra muito bem no espírito da comunidade.

O pmg já demonstrou como podes resolver alguns dos problemas para os quais pediste ajuda. Se não tiveres entendido alguma parte, diz! Com toda a certeza alguém tentará ajudar-te a entendê-la :)


Desaparecido.

Share this post


Link to post
Share on other sites
pmg
Se não te importas, formula a resposta com código completo.

Passo a explicar as alterações propostas:

1) metes a função main() toda (excepto as variáveis locais) dentro dum "forever" (for(;;) { /* codigo */ } ou while(1) { /* codigo */ })

int main (void) {
  /* variaveis locais */
  for(; {
    /* função main() toda */
  }
}

2) Como agora tens switch dentro do for(), um break sai do switch, mas queres sair do for(). Então, antes de entrar no switch testas se queres sair do for()

if (op == 5) break; /* sai do for() */
switch (op) { /* cases; o break sai do switch */ }

3) Dentro de cada case do switch, removes a chamada recursiva ao main().

Quando o programa voltar a repetir o for(), volta a chamar o menu e a aceitar nova opção.

E pronto, acho que é tudo.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.