Jump to content

Listas Ligadas e Ficheiros


mrodriguez
 Share

Recommended Posts

Boas,

Estou a tentar ler de um ficheiro de texto vários numeros. Só que quando mostro todo o conteudo da lista ligada ele apenas mostra os ultimos numeros do ficheiro.

Já andei às voltas com isto e nao consigo por a funcionar.

O ficheiro de texto consiste em :

1 2 3

4 5 6

7 8 9

#include<stdio.h>


typedef struct Mesa m, *pmesa;

struct Mesa{
int id_mesa;		/* nome do item */
int num_lugares;	/* identificador numérico */
int ocupacao;		/*Tem valor zero ou 1. Zero - Livre| 1 - Ocupado*/
pmesa prox;	
};

pmesa coloca_mesa(pmesa lista)
{

pmesa novo, aux;
int z, x, y;
FILE *f;

f=fopen("mesas.txt", "r");

if(f==NULL)
	printf("Erro ao abrir o ficheiro.\n");
else
{
	novo=malloc(sizeof(struct Mesa));
	if(novo==NULL){
		printf("Erro na alocação da memória.\n");
		return lista;
	} else{
		while(fscanf(f, "%d %d %d", &novo->id_mesa, &novo->num_lugares, &novo->ocupacao)!=EOF)
		{
			//printf("ID_MESA:%d\tLUGARES:%d\tOCUPACAO:%d\n",lista->id_mesa, lista->num_lugares, lista->ocupacao);
			novo->prox = NULL;

		}

		novo->prox=lista;
		lista=novo;
	}

}
fclose(f);
return lista;

}

void mostra_res(pmesa p)
{
while(p!=NULL)
{
	printf("Id_mesa:%d\tNum_lugares:%d\tOcupacao:%d\n", p->id_mesa, p->num_lugares, p->ocupacao );
	p=p->prox;

}

}

int main (void)
{

pmesa lista=NULL;


lista=coloca_mesa(lista);
mostra_res(lista);

}
Link to comment
Share on other sites

Eu já consegui por a lista a funcionar.

O problema agora está no mostrar.

A lista está a ser mostrada do ultimo nó para o primeiro. Nao consigo perceber o porque.

Código:

#include<stdio.h>


typedef struct Mesa m, *pmesa;

struct Mesa{
int id_mesa;		/* nome do item */
int num_lugares;	/* identificador numérico */
int ocupacao;		/*Tem valor zero ou 1. Zero - Livre| 1 - Ocupado*/
pmesa prox;	
};

pmesa coloca_mesa(pmesa lista, int x, int y, int z)
{
       pmesa aux;
       
   aux = malloc(sizeof(struct Mesa));
   
   aux->id_mesa = x;
   aux->num_lugares=y;
   aux->ocupacao=z;
       aux->prox = lista;
       return aux;
}




void mostra_res(pmesa p)
{


while(p!=NULL)
{
	printf("Id_mesa:%d\tNum_lugares:%d\tOcupacao:%d\n", p->id_mesa, p->num_lugares, p->ocupacao );
	p=p->prox;

}

}

int main (void)
{

pmesa lista=NULL;
FILE *f;
int x, y, z;


f=fopen("mesas.txt", "r");

if(f)
{
	do{
		fscanf(f, "%d %d %d", &x, &y, &z);

		lista=coloca_mesa(lista, x, y, z);

	}while(!feof(f));

}

mostra_res(lista);

}
Link to comment
Share on other sites

Sim. Para inserires no fim há 2 opções:

1) Sempre que queres inserir, percorres a lista até ao fim, alocas memória para o nó, fazes as inicializações e no fim atribuis o ultimo->prox ao novo nó criado (esta solução corre em tempo linear no tamanho da lista, isto é, O(n), sendo n o tamanho da lista);

2) A tua lista passa a ser formada por 2 apontadores (um para o 1º e outro para o último elemento), para além da definição dos nós, o que te permite inserir na cabeça ou no fim em tempo constante, uma vez que mallocs e atribuições são operações que correm em tempo constante, ou seja, O(1).

Link to comment
Share on other sites

Fiz uma nova função mas nao estou a funcionar.

Conseguem detectar o erro?

pmesa coloca_mesa(pmesa lista, int x, int y, int z)
{
pmesa novo, aux;
       
novo = malloc(sizeof(struct Mesa));

if(novo==NULL)
{
	printf("Erro na alocacao na memória.\n");
	return(lista); 
}

novo->id_mesa = x;
novo->num_lugares=y;
novo->ocupacao=z;
   
if(lista)
	lista=novo;
else{
	aux=lista;
	while(aux->prox!=NULL)
		aux=aux->prox;
	aux->prox=novo;
}
     
return lista;
}
Link to comment
Share on other sites

Se tu leste o post do Baderous percebes que é melhor usares dois ponteiros, um com a cabeça da lista e outra com o fim da mesma, assim é muito mais fácil de adicionares e percorreres a lista quando quiseres.

Depois, o que eu quis dizer é que a adição tem de passar por uma verificação, que vê se o argumento passado à mesma é igual a NULL, se for, então esse próprio argumento vai receber a célula que criaste, que no teu código chamasse novo e retornas logo isso, se não for igual a NULL então tens de fazer com que o next (o ponteiro que aponta para a próxima célula) receba a nova célula e retornas esse next.

List *add(List *tail, int val) {
  List *new=(List *)malloc(sizeof(List));
  new->key=val;
  new->next=NULL;
  if(tail == NULL) {
     tail=new;
     return tail;
  }
  tail->next=new;
  return tail->next;
}

 

Esta seria uma função básica de adição a uma lista.

here since 2009

Link to comment
Share on other sites

Sim. Para inserires no fim há 2 opções:

1) Sempre que queres inserir, percorres a lista até ao fim, alocas memória para o nó, fazes as inicializações e no fim atribuis o ultimo->prox ao novo nó criado (esta solução corre em tempo linear no tamanho da lista, isto é, O(n), sendo n o tamanho da lista);

2) A tua lista passa a ser formada por 2 apontadores (um para o 1º e outro para o último elemento), para além da definição dos nós, o que te permite inserir na cabeça ou no fim em tempo constante, uma vez que mallocs e atribuições são operações que correm em tempo constante, ou seja, O(1).

E como se faz isso?

Por a apontar para o inicio sei, pro fim é que já nao (pelo menos para depois mexer com ele)...

Link to comment
Share on other sites

Não estou a conseguir.

Tenho estas estruturas:

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

typedef char Filme[60];
typedef struct sLBilhete
  {
    int lugar;
    struct sLBilhete *seg;
  } *LBilhete, NLBilhete;
typedef struct sSala
  {
    int nlugares;
    LBilhete vendidos;
    Filme filme;
  } Sala;
typedef struct sCinema
  {
    Sala s;
    struct sCinema *seg;
  } *Cinema, NCinema;

E esta função:

/**
* Da como resultado um novo cinema resultante de acrescentar o lugar lugar a lista dos lugares ocupados na sala onde esta a ser exibido o filme f
**/
Cinema vendebilhete(Cinema c, Filme f, int lugar){
Cinema *head=NULL;
Cinema *last=NULL;
head=&c;
while(c!=NULL){
	if(c->seg==NULL){
		last=&c;
	}
	c=c->seg;	
}
c=*last;
c->seg=malloc(sizeof(struct sCinema)); //erro aqui
c->seg->s.vendidos->lugar=lugar;

return *head;
}

Dá-me segmentation fault naquela linha :\

Link to comment
Share on other sites

E como se faz isso?

Por a apontar para o inicio sei, pro fim é que já nao (pelo menos para depois mexer com ele)...

Construindo uma estrutura assim:

typedef struct node {
int elem;
struct node *next;
} Node;

typedef struct list {
Node *first;
Node *last;
} List;
Link to comment
Share on other sites

Last é um ponteiro que contém um endereço, ao fazeres c=*last; estás a receber em c (que também é um ponteiro) o valor apontado por last, ou seja, isso vai ser interpretado como um endereço, depois trabalhas com esse ponteiro mas estás a trabalhar numa posição indefinida.

here since 2009

Link to comment
Share on other sites

Tenho estas estruturas:

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

typedef char Filme[60];
typedef struct sLBilhete
  {
    int lugar;
    struct sLBilhete *seg;
  } *LBilhete, NLBilhete;
typedef struct sSala
  {
    int nlugares;
    LBilhete vendidos;
    Filme filme;
  } Sala;
typedef struct sCinema
  {
    Sala s;
    struct sCinema *seg;
  } *Cinema, NCinema;

E esta função:

/**
* Insere a sala s no cinema c e retorna este ultimo como parametro
**/
Cinema inserirSala(Cinema c, Sala s){
Cinema *head=NULL;
head=&c;
if(c==NULL){
	c=malloc(sizeof(struct sCinema));
	c->s=s;
	c->seg=NULL;
}
else{
	while(c->seg!=NULL){
		c=c->seg;
	}
	c=c->seg;
	c=malloc(sizeof(struct sCinema));
	c->s=s;
	c->seg=NULL;
}
return *head;
}

Agora estou com outro problema: ao inserir duas salas, a 2ª vai para a cabeça da lista e a 1ª desaparece. Qual e o erro?

Link to comment
Share on other sites

Mais uma vez, deixo aqui um exemplo de inserção numa lista ligada:

List *add(int val, List *tail) {
  List *new=(List *)malloc(sizeof(List));  
  new->key=val;
  new->next=NULL;
  if(tail==NULL) {
     tail=new;
     return tail;
  }
  tail->next=new;
  return tail->next; 
}

Como podes ver eu retorno sempre o final da lista, espero que este exemplo te possa ajudar.

here since 2009

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
 Share

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