Jump to content

Loop inifinito em listas ligadas


alphasil

Recommended Posts

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.

gmc11

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

gmc11

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
gmc11

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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;
gmc11

 

Link to comment
Share on other sites

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
gmc11

 

Link to comment
Share on other sites

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
gmc11

 

Link to comment
Share on other sites

é 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
Link to comment
Share on other sites

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

gmc11

 

Link to comment
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
×
×
  • 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.