Jump to content
Sign in to follow this  
alphasil

Loop inifinito em listas ligadas

Recommended Posts

alphasil

Oi

Estou a continuar a trabalhar para o exame e apesar de não me pedir isso estou a fazer as funções todas de listas ligadas e agora ao listar tenho um loop infinito e não estou a perceber o porquê, alguma alma me ajude se faz favor?

#include <stdio.h>
#include <stdlib.h>
typedef struct eng
{
   char nomes[100];
   char curso[100];
   char inst[100];
   int nota;
   char curri[100];
}INFO;
typedef struct elemento
{
   INFO nodo;
   struct elemento *seguinte;
   struct elemento *anterior;
}ELEM;
int insCandidatos(INFO info, ELEM **initLista, ELEM **fimLista)
{
   ELEM *novo;
   novo=(ELEM*)malloc(sizeof(ELEM));
   if(novo==NULL)
   {
    printf("Erro na lista");
    return -1;
   }
   novo->nodo=info;
   novo->seguinte=NULL;
   novo->anterior=NULL;
   if(*initLista==NULL)
   {
    *initLista=novo;
    *fimLista=novo;
   }
   novo->seguinte=novo;
   (*initLista)->anterior=*initLista;
   *initLista=novo;
   return 0;
}
int listarInicio(ELEM *initLista)
{
   ELEM *aux;
   if(iniLista==NULL)
   {
    printf("lista vazia!\n");
    return -1;
   }
   aux= initLista;
   while(aux!=NULL)
   {
    printf("%s  %s  %s %d   %s", aux->nodo.nomes, aux->nodo.curso, aux->nodo.inst, aux->nodo.nota, aux->nodo.curri);
    aux=aux->seguinte;
   }
   return 0;
}
int listarMaiorCatorze(ELEM *initLista)
{
   ELEM *aux;
   aux= initLista;
   if(aux->nodo.nota>14)
   {
    printf("%s  %d", aux->nodo.nomes,aux->nodo.nota);
    aux=aux->seguinte;
   }
   return 0;
}
int main()
{
   ELEM *initLista=NULL, *fimLista=NULL;
   INFO info;
   int op;
   do
   {
    printf("Nome: \n");
    gets(info.nomes);
    printf("Curso: \n");
    gets(info.curso);
    printf("Instituicao: \n");
    gets(info.inst);
    printf("Nota: \n");
    scanf("%d", &info.nota);
    getchar();
    printf("Curriculo: \n");
    gets(info.curri);
    printf("Mais: \n");
    scanf("%d", &op);
    getchar();
   }
   while(op!=0);
   insCandidatos(info,&initLista, &fimLista);
   listarInicio(initLista);
   listarMaiorCatorze(initLista);
   return 0;
}

Já agora, a função listaMaiorCatorze deve mostrar o nome e a nota daqueles que têm mais de catorze, está bem implementada??

Obrigado.

Share this post


Link to post
Share on other sites
HappyHippyHippo

tenho um felling que o problema está no método de leitura de dados de teclado.

o uso de gets/scanf ... uff ... quantas vezes aqui no fórum se disse para ter cuidado com isso ...

adiciona este código e usa-o a teu belo prazer

int readInt(int * result) {
 char buffer[256];

 if (fgets(buffer, 256, stdin) == NULL)
   return -1;
 if (sscanf(buffer, "%d", result) != 1)
   return -2;
 return 0;
}
int readString(char * result, size_t result_size) {
 if (fgets(result, result_size, stdin) == NULL)
   return -1;
 return 0;
}

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Eu sei que já me disseste como o exame é feito a papel....não estou a dar importância ao gets/fgets,

Quanto aquela função, está bem ou nem por isso??

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Usei o fgets e sscanf e continua na mesma com loop infinito

#include <stdio.h>
#include <stdlib.h>
typedef struct eng
{
   char nomes[100];
   char curso[100];
   char inst[100];
   int nota;
   char curri[100];
}INFO;
typedef struct elemento
{
   INFO nodo;
   struct elemento *seguinte;
   struct elemento *anterior;
}ELEM;
int insCandidatos(INFO info, ELEM **initLista, ELEM **fimLista)
{
   ELEM *novo;
   novo=(ELEM*)malloc(sizeof(ELEM));
   if(novo==NULL)
   {
    printf("Erro na lista");
    return -1;
   }
   novo->nodo=info;
   novo->seguinte=NULL;
   novo->anterior=NULL;
   if(*initLista==NULL)
   {
    *initLista=novo;
    *fimLista=novo;
   }
   novo->seguinte=novo;
   (*initLista)->anterior=*initLista;
   *initLista=novo;
   return 0;
}
int listarInicio(ELEM *initLista)
{
   ELEM *aux;
   if(initLista==NULL)
   {
    printf("lista vazia!\n");
    return -1;
   }
   aux= initLista;
   while(aux!=NULL)
   {
    printf("%s  %s  %s %d   %s", aux->nodo.nomes, aux->nodo.curso, aux->nodo.inst, aux->nodo.nota, aux->nodo.curri);
    aux=aux->seguinte;
   }
   return 0;
}
int listarMaiorCatorze(ELEM *initLista)
{
   ELEM *aux;
   aux= initLista;
   if(aux->nodo.nota>14)
   {
    printf("%s  %d", aux->nodo.nomes,aux->nodo.nota);
    aux=aux->seguinte;
   }
   return 0;
}
int main()
{
   ELEM *initLista=NULL, *fimLista=NULL;
   INFO info;
   int op;
   char buf[30];
   do
   {
    printf("Nome: \n");
    fgets(info.nomes, 100, stdin);
    printf("Curso: \n");
    fgets(info.curso, 100, stdin);
    printf("Instituicao: \n");
    fgets(info.inst, 100, stdin);
    printf("Nota: \n");
    fgets(buf, 100, stdin);
    sscanf(buf, "%d", &info.nota);
    printf("Curriculo: \n");
    fgets(info.curri, 100, stdin);
    printf("Mais: \n");
    scanf("%d", &op);
    getchar();
   }
   while(op!=0);
   insCandidatos(info,&initLista, &fimLista);
   listarInicio(initLista);
   listarMaiorCatorze(initLista);
   return 0;
}

Não estou a ver....

Share this post


Link to post
Share on other sites
HappyHippyHippo

então é mesmo na limpeza do buffer de leitura, usa as funções que te apresentei


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Ótimo, isso quer dizer que se fizesse isso sem ser no pc estava certo, o que é estranho é que os exemplos que o prof dá são com gets. lol

Olha uma coisa, a função listarMaiorCatorze está certa??

Obrigado pela tua ajuda

Share this post


Link to post
Share on other sites
HappyHippyHippo

Obrigado pela tua ajuda

Não porque não estás a verificar todos os elementos da lista mas sim somente o primeiro e estás a assumir que existe o primeiro.

Se imaginares que a lista se encontra vazia, o ponteiro encontrasse a nulo o que irá causar erro de acesso de memória ao executar a função


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Esse problema já o resolvi

Ficou assim, estava a repetir o aux=aux->seguinte.

int print(ELEM *initLista)
{
ELEM *aux;
if(initLista==NULL){
				 printf("lista vazia!\n");
				 return -1;
				 }
aux=initLista;
for(aux=initLista;aux!=NULL;aux=aux->seguinte)
{
 printf("%s %s %s %d %s\n",aux->nodo.nomes,aux->nodo.curso,aux->nodo.inst,aux->nodo.nota, aux->nodo.curri);
}
return 0;
}

Já agora, se me pedirem o próximo elemento a ser atendido numa fila, uso isso?

int nextOnList(ELEM *initLista)
{
if(initLista==NULL)
{
	printf("Fila Vazia...");
	return -1;
}
printf("\n%s\n", initLista->nodo.nomes);
return 0;
}

Edited by alphasil

Share this post


Link to post
Share on other sites
HappyHippyHippo

não te consigo responder se sim ou não porque a tua implementação de fila está um pouco baralhada principalmente no código de inserção.

estás a inserir novos elementos à cabeça ou na cauda da fila ?? estás a tirar da cabeça ou da cauda ??


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

No fim da lista

int enqueue(INFO info, ELEM **initLista, ELEM **fimLista)
{
   ELEM *novo;
   novo=(ELEM*)malloc(sizeof(ELEM));
   if(novo==NULL)
   {
    printf("Erro na lista");
    return -1;
   }
   novo->nodo=info;
   novo->seguinte=NULL;
   novo->anterior=NULL;
   if(*initLista==NULL)
   {
    *initLista=novo;
    *fimLista=novo;
   }
   else
   {
   novo->anterior=*fimLista;
   (*fimLista)->seguinte=novo;
   *fimLista=novo;
   }
   return 0;
}

Se for no início só tenho de usar o contrário, não é?

 
novo->seguinte=*initLista;
   (*initLista)->anterior=novo;
   *initLista=novo;

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Mas se a inserção for feita no início da lista então o próximo a ser atendido terá de ser o contrário ou seja:

int nextOnList(ELEM *fimLista)
{
 if(fimLista==NULL)
 {
		 printf("Fila Vazia...");
		 return -1;
 }
 printf("\n%s\n", fimLista->nodo.nomes);
 return 0;
}

certo?

Edited by alphasil

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Estou a fazer um exercício de exame que diz:

a) Sabendo que a fila é implementada recorrendo ao uso de uma lista ligada, defina a estrutura de dados - FEITO

b)Implementar a função insAnimal() que vai inserir animais- FEITO

c) Implemente a função proximoAnimal() que retorna info sobre o proximo animal a ser atendido - FEITO PARCIALMENTE

São atendidos por ordem de chegada, depois de inserir vai sempre buscar o último....

#include <stdio.h>
#include <stdlib.h>
typedef struct animal{
char especie[100],raca[100], dono[100];
int idade;
float preco;
}INFO;
typedef struct elemento{
INFO nodo;
struct elemento *seguinte;
struct elemento *anterior;
}ELEM;

//Inserçao no inicio da fila
int insAnimal(INFO info, ELEM **initLista, ELEM **fimLista)
{
ELEM *novo;
novo=(ELEM*)malloc(sizeof(ELEM));
if(novo==NULL)
{
	printf("Erro na lista");
	return -1;
}
novo->nodo=info;
novo->seguinte=NULL;
novo->anterior=NULL;
if(*initLista==NULL)
{
	*initLista=novo;
	*fimLista=novo;
}
else
{
	novo->seguinte=*initLista;
	(*initLista)->anterior=*initLista;
	*initLista=novo;
}
/*
Se for no fim da fila
novo->anterior=*fimLista;
(*fimLista)->seguinte=*fimLista;
*fimLista=novo;
*/
return 0;
}
//Proximo elemento da fila a ser atendido com inserção no inicio da Fila
int proximoAnimal(ELEM *fimLista)
{
if(fimLista==NULL)
{
	printf("Fila Vazia...");
	return -1;
}
printf("\n%s\n", fimLista->nodo.dono);
return 0;
}
int main()
{
ELEM *initLista=NULL, *fimLista=NULL;
INFO info;
int i;
for(i=0; i<2; i++)
{
   printf("Especie: \n");
   fgets(info.especie,100, stdin);
	printf("raca: \n");
   fgets(info.raca,100, stdin);
	printf("Dono: \n");
   fgets(info.dono,100, stdin);
   printf("Idade: \n");
   scanf("%d", &info.idade);
   getchar();
   printf("Preco: \n");
   scanf("%f", &info.preco);
   getchar();
}
insAnimal(info,&initLista,&fimLista);
printf("\nProximo animal a ser atendido.");
proximoAnimal(initLista);
return 0;
}

??

Edited by alphasil

Share this post


Link to post
Share on other sites
HappyHippyHippo

é uma fila, lê isto para perceberes o que se pretende

logo as funções deveriam ter este protótipo

/// função que insere um elemento na lista
///
/// @param INFO info : estrutura com a informação a ser inserida na lista
/// @param ELEM ** initLista : Ponteiro para o ponteiro para o primeiro elemento da lista
/// @param ELEM ** fimLista : Ponteiro para o ponteiro para o último elemento da lista
///
/// @return Retorna 0 em caso de sucesso ou outro valor em caso de erro
int insAnimal(INFO info, ELEM **initLista, ELEM **fimLista);

/// função que lê (e retira) o elemento da lista
///
/// @param INFO * info : ponteiro para uma estrutura que irá conter a informação lida da lista
/// @param ELEM ** initLista : Ponteiro para o ponteiro para o primeiro elemento da lista
/// @param ELEM ** fimLista : Ponteiro para o ponteiro para o último elemento da lista
///
/// @return Retorna 0 em caso de sucesso ou outro valor em caso de erro
int proximoAnimal(INFO * info, ELEM **initLista, ELEM **fimLista);


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Logo vi que era muito simples...lol

Neste caso quer dizer que ao dizer proximo estou a dizer que vou tirá-lo da fila, usando o dequeue, certo?

Share this post


Link to post
Share on other sites
HappyHippyHippo

exatamente ... as duas operações fundamentais da fila(queue)

PS : já agora tenho de te dar os parabéns porque pareces estar a evoluir bastante bem

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Obrigado mas é graças a ti e as tuas explicações, nem sei como te agradecer.

Bem já fiz o dequeue mas estou na mesma com uns problemas.

1 .Ponho 2 registos e na listagem só me aparece um

2. No dequeue tira-me o segundo elemento, em vez do primeiro, a não ser que não esteja a gravar o primeiro, podes testar se faz favor HHH?

#include <stdio.h>
#include <stdlib.h>
typedef struct animal{
   char especie[100],raca[100], dono[100];
   int idade;
   float preco;
}INFO;
typedef struct elemento{
   INFO nodo;
   struct elemento *seguinte;
   struct elemento *anterior;
}ELEM;

//Inserçao no inicio da fila
int insAnimal(INFO info, ELEM **initLista, ELEM **fimLista)
{
   ELEM *novo;
   novo=(ELEM*)malloc(sizeof(ELEM));
   if(novo==NULL)
   {
    printf("Erro na lista");
    return -1;
   }
   novo->nodo=info;
   novo->seguinte=NULL;
   novo->anterior=NULL;
   if(*initLista==NULL)
   {
    *initLista=novo;
    *fimLista=novo;
   }
   else
   {
    novo->seguinte=*initLista;
    (*initLista)->anterior=*initLista;
    *initLista=novo;
   }
   /*
   Se for no fim da fila
   novo->anterior=*fimLista;
   (*fimLista)->seguinte=*fimLista;
   *fimLista=novo;
   */
   return 0;
}

int listarInicio(ELEM *initLista)
{
   ELEM *aux;
   if(initLista==NULL)
   {
    printf("Fila Vazia...");
    return -1;
   }
   aux=initLista;
   for(aux=initLista; aux!=NULL; aux=aux->seguinte)
   {
    printf("%s  %s  %s  %d  %.2f \n", aux->nodo.especie,aux->nodo.raca, aux->nodo.dono, aux->nodo.idade, aux->nodo.preco);
   }
   return 0;
}
//Proximo elemento da fila a ser atendido com inserção no inicio da Fila
int proximoAnimal(INFO info, ELEM **initLista, ELEM **fimLista)
{
   ELEM *aux;
   aux = *initLista;
   if(aux==NULL)
   {
    printf("Fila Vazia...");
    return -1;
   }
   if(aux->anterior==NULL)
   {
    printf("Elemento retirado... %s", aux->nodo.dono);
    *initLista=aux->seguinte;
    if(*initLista)
    *initLista=aux->anterior=NULL;
   }
   else
   printf("Elemento n existe...");
   return 0;
}
//fUNCAO TOTAL DE IDADES
int totIdades(ELEM *initLista)
{
   if(initLista==NULL)
   {
    printf("Fila Vazia...");
    return -1;
   }
   return(initLista->nodo.idade+totIdades(initLista->seguinte));
}

int main()
{
   ELEM *initLista=NULL, *fimLista=NULL;
   INFO info;
   int i;
   for(i=0; i<2; i++)
   {
   printf("Especie: \n");
   fgets(info.especie,100, stdin);
    printf("raca: \n");
   fgets(info.raca,100, stdin);
    printf("Dono: \n");
   fgets(info.dono,100, stdin);
   printf("Idade: \n");
   scanf("%d", &info.idade);
   getchar();
   printf("Preco: \n");
   scanf("%f", &info.preco);
   getchar();
   }
   insAnimal(info,&initLista,&fimLista);
   printf("\nProximo animal a ser atendido.");
   listarInicio(initLista);
   proximoAnimal(info,&initLista,&fimLista);
   //totIdades(initLista);
   listarInicio(initLista);
   return 0;
}

Obrigado

Share this post


Link to post
Share on other sites
HappyHippyHippo

se inseres no início, tens de tirar do fim

+--+          +--+  +--+  +--+          +--+
|  |-inserir->|  |->|  |->|  |-retirar->|  |
+--+          +--+  +--+  +--+          +--+

no entanto não percebo o teu código, pareces que ignoraste o que te disse no posts anterior:

/// função que lê (e retira) o elemento da lista
///
/// @param INFO * info : ponteiro para uma estrutura que irá conter a informação lida da lista
/// @param ELEM ** initLista : Ponteiro para o ponteiro para o primeiro elemento da lista
/// @param ELEM ** fimLista : Ponteiro para o ponteiro para o último elemento da lista
///
/// @return Retorna 0 em caso de sucesso ou outro valor em caso de erro
int proximoAnimal(INFO * info, ELEM **initLista, ELEM **fimLista);


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Desculpa, tive de sair,

Eu li o teu post e alterei os parâmetros da função proximoAnimal()

Se estamos a falar de fifo, o primeiro elemento a entrar é o primeiro a sair, mas a questão aqui é que insiro dois elementos e não me aparecem os dois mas sim um...

Share this post


Link to post
Share on other sites
HappyHippyHippo

esta é a razão que eu disse para comentares o código, é para facilitar a sua leitura e perceber onde está o erro, porque novamente foi algo demasiado simples :

   for (i = 0; i < 2; i++) {
       // ...
   }
   insAnimal(info, &initLista, &fimLista);

então diz lá quantas vezes estas a chamar a função de inserir ??


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
alphasil

Oi HHH

Resolvido, o prof induziu-me em erro nos apontamentos, diz que é

novo->anterior=*fimLista;
       (*fimLista)->seguinte=*fimLista;
       *fimLista=novo;

quando deveria ser

novo->anterior=*fimLista;
       (*fimLista)->seguinte=novo;
       *fimLista=novo;

Agora já aparece tudo e retira o primeiro.

Mais uma vez...obrigado pela paciência :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

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.