PDA

Visualizza la versione completa : [C] Funzione stampa lista di liste ed errore "segmentation fault"


trapanina
06-09-2011, 18:04
Ciao ragazzi,
sono alle prese con la programmazione in c e ho qualche problema con la funzione stampa nella lista di liste.
Il debug mi dice che c'è un errore di segmentazione e se provo ad eseguirlo si crasha!! :dhò:
mi sapete aiutare???
vi posto il codice:



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 30
#define fcentraline "centraline.txt"

typedef struct Atomodati{
int ora;
int min;
char data[LEN];
float temp;
float press;
float umid;
}Atomodati,Tatomodati;

typedef struct Lista_dati{
Atomodati dato;
struct Lista_dati *succ;
}Lista_dati,*Tlista_dati;

typedef struct Atomocentraline{
int id;
char ubicazione[LEN];
int tipo;
Tlista_dati dati_ril;
}Atomocentraline,Tatomocentraline;

typedef struct Lista_centraline{
Atomocentraline dato;
struct Lista_centraline *succ;
}Lista_centraline,*Tlista_centraline;

void cons(Tlista_centraline *l,Atomocentraline e)
{
Tlista_centraline tmp;
tmp=(Tlista_centraline)malloc(sizeof(Lista_central ine));

if(tmp==NULL)
{
printf("errore 1 \n");
system("pause");
exit(-1);
}

tmp->dato=e;
tmp->succ=*l;
(*l)=tmp;
}
void cons2(Tlista_dati *l,Atomodati e)
{
Tlista_dati tmp;
tmp=(Tlista_dati)malloc(sizeof(Lista_dati));

if(tmp==NULL)
{
printf("errore 2 \n");
system("pause");
exit(-1);
}

tmp->dato=e;
tmp->succ=*l;
(*l)=tmp;
}


void insord_dati(Tlista_dati *l,Atomodati e)
{
if(((*l)==NULL)||(strcmp((*l)->dato.data,e.data)<0)) cons2 (l,e);
else insord_dati(&(*l)->succ,e);
}

void insord_centraline(Tlista_centraline *l,Atomocentraline e)
{
if(((*l)==NULL)||((*l)->dato.id<e.id)) cons (l,e);
else insord_centraline(&(*l)->succ,e);
}

void carica_lista(Tlista_centraline *l)
{
Atomocentraline c;
Atomodati d;
FILE *fp;

fp=fopen (fcentraline,"r");
while (fscanf(fp,"%d",&c.id)!=EOF)
{
fgets(c.ubicazione,LEN,fp);
c.ubicazione[strlen(c.ubicazione)-1]='\0';
fscanf(fp,"%d",&c.tipo);
c.dati_ril=NULL;
cons (l,c);
while(fscanf(fp,"%d",&d.ora)!=EOF)
{
fscanf(fp,"%d",&d.min);
fgets(d.data,LEN,fp);
d.data[strlen(d.data)-1]='\0';
fscanf(fp,"%f",&d.temp);
fscanf(fp,"%f",&d.press);
fscanf(fp,"%f",&d.umid);
cons2(&((*l)->dato.dati_ril),d);
}
}printf("liste caricate\n");
fclose(fp);
}

//data id e ora stampare tutte le ubicazioni

void stampa (Tlista_centraline l) {
int x,y;
Tlista_dati tmp;
printf ("inserisci id\n");
scanf ("%d",&x);
printf ("inserisci ora\n");
scanf ("%d",&y);
while (l!=NULL) {
tmp=l->dato.dati_ril;
if (l->dato.id==x && tmp->dato.ora==y)
printf ("ecco le ubicazioni che cercavi %d",l->dato.ubicazione);
l=l->succ;
}
}

int main()
{

Tlista_dati ld;
Tlista_centraline lc;
carica_lista(&lc);
stampa(ld);
system("pause");
return 0;
}

Formattazione codice aggiunta da Alka

alka
06-09-2011, 18:09
Il linguaggio va indicato nel titolo, come da Regolamento (http://forum.html.it/forum/showthread.php?s=&threadid=973887), e il codice va formattato usando l'apposito tag [CODE].

Qui ho aggiunto io entrambi, in futuro provvedi tu.

Ciao! :ciauz:

trapanina
06-09-2011, 18:12
Ah grazie mille :)
In futuro provvederò ;)

trapanina
08-09-2011, 12:05
Perchè non mi risponde nessuno??
Aiuto ragazzi tra qualche giorno ho il compito e il programma non và proprio :(

valia
08-09-2011, 12:26
non ho eseguito il tuo codice, ma parto dall'errore e da quello che scrivi.
L'errore è segmentation fault, fin'ora quando ho visto questo errore ho provato l'accesso a memoria non inizializzata oppure sono andata fuori dal mio spazio di esecuzione.

Questa è la tua funzione di stampa



void stampa (Tlista_centraline l) {
int x,y;
Tlista_dati tmp;
printf ("inserisci id\n");
scanf ("%d",&x);
printf ("inserisci ora\n");
scanf ("%d",&y);
while (l!=NULL) {
tmp=l->dato.dati_ril;
if (l->dato.id==x && tmp->dato.ora==y)
printf ("ecco le ubicazioni che cercavi %d",l->dato.ubicazione);
l=l->succ;
}
}


guarda la funzione, il primo controllo è mettere delle printf prima di ogni istruzione (o debuggare) per sapere a che punto arrivi. Tipo questo




void stampa (Tlista_centraline l) {
int x,y;
Tlista_dati tmp;
printf ("inserisci id\n");
scanf ("%d",&x);
printf ("inserisci ora\n");
scanf ("%d",&y);
printf("l'input l'ho preso\n");
while (l!=NULL) {
printf("dentro ciclo prima di assegnare temp\n");
tmp=l->dato.dati_ril;
printf("dentro ciclo dopo aver assegnato temp\n");
if (l->dato.id==x && tmp->dato.ora==y){

printf ("ecco le ubicazioni che cercavi %d",l->dato.ubicazione);
}
printf("dopo if\n");
l=l->succ;
printf("ultima istruzione\n");
}
}


provi e vedi a che punto arrivi. La prima printf che non vedi ti fa capire che all'istruzione prima fai qualcosa che non devi.

Secondo me la struttura che passi ha qualche valore a NULL (che non controlli)

trapanina
08-09-2011, 12:38
Così mi stampa tutto tranne la printf che a me interessava di più :

printf ("ecco le ubicazioni che cercavi %d",l->dato.ubicazione);

valia
08-09-2011, 12:45
ok significa che uno dei due parametri che controlli non è valorizzato,prova a mettere


if (l->dato.id==x && tmp->dato.ora==y){


quindi è questa che lo manda in botta.
Allora controlla che

x sia valorizzato
y sia valorizzato
l->dato.id sia valorizzato
tmp->dato.ora sia valorizzato

banalmente farei una printf di questi valori
In generale in questi casi devi controllare che alla riga prima della printf che non vedi sia tutto valorizzato e valorizzato correttamente

trapanina
08-09-2011, 12:48
scusa l'ignoranza, ma cosa intendi per valorizzati??
non gli assegno un valore nel momento in cui pongo l->dato.id==x e tmp->dato.ora==y ??
cosa dovrei fare?

valia
08-09-2011, 12:52
valorizzati == che tu gli abbia assegnato un valore.

No, qui fai un controllo

l->dato.id==x

ti chiedi se il valore di x sia uguale (==) a quello di l->dato.id.

non confondere l'operatore di assegnamento e quello di confronto

trapanina
08-09-2011, 12:56
ah grazie :sbav: :)
però ho provato a mettere int x e int y = 0 ma nn appare neanke facendo così .
Come mi consigli di valorizzarli?

Loading