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

metaclay

Gestão de músicas

14 mensagens neste tópico

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();
     
     
     }

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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"))

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

a) NUNCA USES gets()

Podias dizer o motivo. Eu pelo menos não faço deia qual seja.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
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.
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
/* ... #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;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
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?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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. :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
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.

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