 
View Full Version : [C]ricordare inizio lista
blindwrite
29-02-2008, 10:23
vi allego parte del mio codice non funzionante
elemento=curr->puntatore;
ricordo=curr->puntatore;
 int giorni;
       int i;                      
       int z;
       
    
       for(z=0;z<settimane;z++){ //settimane è una valore che ho dal resto del programma
                 elemento=(settimana*)malloc(sizeof(settimana));
                 fscanf(fp,"%d%d", &elemento->numero,&elemento->giorni);
      
     
     
      
                  giorni=elemento->giorni;
       
       for(i=0;i<giorni;i++){
                                fscanf(fp,"%d",&elemento->ore[i]);
                                }
                                elemento=elemento->succ;
                               
      }
//comincio la stampa (errore di segmentazione)
         for(z=0;z<settimane;z++){
         printf("%d %d ",ricordo->numero,ricordo->giorni);
       
       
       
       for(i=0;i<giorni;i++){
                                printf("%d ", ricordo->ore[i]);
                                }
                                printf("\n");
       ricordo=ricordo->succ;
                                }
          
quello che dovrebbe fare ma non fa:
elemento e ricordo all'inizio devono puntare alla stessa cosa
elemento si sposta andando avanti con la lettura del file e la creazione della sottolista
ricordo secondo me dovrebbe tener memorizzato la posizione iniziale della lista, in modo tale da poterla stampare una vola che il caricamento è completato.
purtroppo ricordo->numero non è quello che io credo (ossia il primo campo del primo elemento della lista).
durante l'esecuzione si blocca dando segmentation fault.
non capisco se sbaglio a scrivere il codice oppure sono io che non ho inteso bene a cosa punti ricordo???
grazie a chiunque mi dia una mano:D
wingman87
29-02-2008, 10:56
Premetto che potrei dire caxxate perche' sono un po' a digiuno di C.
Perche' prima del ciclo hai scritto
elemento=curr->puntatore;
se tanto poi all'interno del ciclo lo sovrascrivi?
Inoltre non penso che sia corretto il modo in cui generi la lista nel primo ciclo, cioe', tu fai:
elemento=elemento->succ;
alla fine senza pero' aver dato alcun valore a succ, e poi all'inizio del ciclo fai
elemento=(settimana*)malloc(sizeof(settimana));
quindi stai di nuovo sovrascrivendo l'assegnazione precedente. Nel precedente elemento->succ credo che sia rimasto un puntatore a qualcosa di indefinito. Praticamente stai allocando degli elementi tutti slegati tra loro.
Secondo me sarebbe piu' corretto una cosa del tipo:
elemento->succ=(settimana*)malloc(sizeof(settimana));
elemento=elemento->succ;
Ogni volta che vuoi generare un nuovo elemento legato al precedente.
Per questo stesso motivo ricordo non tiene traccia del primo elemento della lista.
Spero di non aver detto vaccate :)
blindwrite
29-02-2008, 11:03
Premetto che potrei dire caxxate perche' sono un po' a digiuno di C.
Perche' prima del ciclo hai scritto
elemento=curr->puntatore;
se tanto poi all'interno del ciclo lo sovrascrivi?
deriva da parte precedente di codice funzionante.. in pratica sto adesso andando a scrivere in una sottolista della lista principale
Inoltre non penso che sia corretto il modo in cui generi la lista nel primo ciclo, cioe', tu fai:
elemento=elemento->succ;
alla fine senza pero' aver dato alcun valore a succ, e poi all'inizio del ciclo fai
elemento=(settimana*)malloc(sizeof(settimana));
quindi stai di nuovo sovrascrivendo l'assegnazione precedente. Nel precedente elemento->succ credo che sia rimasto un puntatore a qualcosa di indefinito. Praticamente stai allocando degli elementi tutti slegati tra loro.
potrebbe essere come dici tu ma io intendo...
alloco memoria per elemento che tramite spostamento precedente è già al punto giusto ossia elemento=curr->puntatore;, poi alloco la memoria per elemento che è già al punto giusto, scrivo i dati che devo mettere e poi vado avanti con elemento=elemento->succ;
mi stai dicendo di tenere un elemento dummy all'inizio??
se faccio subito elemento->succ=malloc..... non alloco memoria per il blocco successivo??? dove scrivo i dati di adesso??
Secondo me sarebbe piu' corretto una cosa del tipo:
elemento->succ=(settimana*)malloc(sizeof(settimana));
elemento=elemento->succ;
Ogni volta che vuoi generare un nuovo elemento legato al precedente.
Per questo stesso motivo ricordo non tiene traccia del primo elemento della lista.
Spero di non aver detto vaccate :)
provo!
blindwrite
29-02-2008, 11:07
allego tutto il file per chiarezza
#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
typedef struct settimana{
        int numero;
        int giorni;
        int ore[8];
        struct settimana *succ;
        
        }settimana;
typedef struct dipendenti{
        int matricola;
        char cognome[100];
        char nome[100];
        struct dipendenti *succ;
        struct settimana *puntatore;
}dipendenti;
 void crealista(FILE*fp, dipendenti *primo , dipendenti **vet, int k){
      int matricola;
      char nome[20],cognome[20];
      dipendenti *curr;
      int settimane;
      settimana *elemento;
      settimana *ricordo;
      int n;
     // for(n=0;n<k;i++){
       fscanf(fp,"%d",&matricola);
       fscanf(fp,"%s",cognome);
       fscanf(fp,"%s",nome);
       primo->succ=(dipendenti*)malloc(sizeof(dipendenti));
       curr=primo->succ;
       curr->matricola=matricola;
       strcpy(curr->nome,nome);
       strcpy(curr->cognome,cognome);
       elemento=curr->puntatore;
       ricordo=curr->puntatore;
      // elemento=(settimana*)malloc(sizeof(settimana));
       fscanf(fp,"%d", &settimane);// MI DEVO CREARE UN CICLO PER LE SOTTO STRUTTURE
      
     printf("%d %s %s\n",curr->matricola,curr->nome,curr->cognome);
       
   
      /* fscanf(fp,"%d%d", &elemento->numero,&elemento->giorni);
       //LETTURA INFORMAZIONI GIORNATA
      
       int giorni;
       int i;
       giorni=elemento->giorni;
       
       for(i=0;i<giorni;i++){
                                fscanf(fp,"%d",&elemento->ore[i]);
                                }
       
       
       
       
       
       
       
       printf("%d %d ",elemento->numero,elemento->giorni);
       
       
       
       for(i=0;i<giorni;i++){
                                printf("%d ", elemento->ore[i]);
                                }*/
       int giorni;
       int i;                      
       int z;
       
    
       //printf("%d %d", ricordo, elemento);
       for(z=0;z<settimane;z++){
      
   
      elemento=(settimana*)malloc(sizeof(settimana));
      fscanf(fp,"%d%d", &elemento->numero,&elemento->giorni);
      
     
     
      
      giorni=elemento->giorni;
       
       for(i=0;i<giorni;i++){
                                fscanf(fp,"%d",&elemento->ore[i]);
                                }
                                elemento=elemento->succ;
                               
      }
        //printf("\n%d %d\n", ricordo, elemento); 
         for(z=0;z<settimane;z++){
         printf("%d %d ",ricordo->numero,ricordo->giorni);
       
       
       
       for(i=0;i<giorni;i++){
                                printf("%d ", ricordo->ore[i]);
                                }
                                printf("\n");
       ricordo=ricordo->succ;
                                }
          
                                
}
       
      
       //devo vedere come fare per leggere il resto del file e mettere tutto nel posto giusto
      
       
   //    }
int main(void)
{
    FILE *fp;
 fp=fopen("prova.txt", "r");
 if(fp==NULL){
              printf("errore\n");
              return(0);
              }
 else{
      printf("file letto correttamente\n");
      }
     dipendenti **vet;
      int i,a;
      fscanf(fp,"%d",&i); //letto il numero degli impigati
      vet=(dipendenti**)malloc (i); //mi creo un vettore di puntatori di dimensione appropiata
      dipendenti *primo;
      primo=(dipendenti*)malloc (sizeof(dipendenti));
      primo->succ=NULL;
      primo->puntatore=NULL;
      
     
     
  crealista(fp, primo,vet, i);
      
      
system("pause")  ;
}
blindwrite
29-02-2008, 13:53
nessuno...
mi sa che faccio prima a riprendere tutto dall'inizio
:cry:
allora io a rispondere ci provo... :stordita: 
quasi sicuramente risolvi facendo inizializzare ricordo al primo elemento dopo che però questo è stato inserito: inizializzi ricordo a NULL e nel for metti un if che inizializza il puntatore solo se questo ha il valore NULL
blindwrite
29-02-2008, 16:24
mettendo l'if per uguagliare i puntatori dopo che elemento è stato creato con la malloc riesco a stampare il primo nodo della lista utilizzando ricordo come puntatore per stampare... il problema è che ricordo in questo modo sembra essere collegato solo al primo nodo della lista, il successivo invece (al secondo ciclo ) risulta essere scollegato dalla lista puntata da ricordo.
non so se mi sono spiegato.. (credo di no:stordita: )
blindwrite
29-02-2008, 16:54
credo di aver risolto così:
 
#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
typedef struct settimana{
        int numero;
        int giorni;
        int ore[8];
        struct settimana *succ;
        
        }settimana;
typedef struct dipendenti{
        int matricola;
        char cognome[100];
        char nome[100];
        struct dipendenti *succ;
        struct settimana *puntatore;
}dipendenti;
 void crealista(FILE*fp, dipendenti *primo , int k){
      int matricola;
      char nome[20],cognome[20];
      dipendenti *curr;
      int settimane;
      settimana *elemento;
      settimana *ricordo;
      int n;
 for(n=0;n<k;n++){
       fscanf(fp,"%d",&matricola);
       fscanf(fp,"%s",cognome);
       fscanf(fp,"%s",nome);
       primo->succ=(dipendenti*)malloc(sizeof(dipendenti));
       curr=primo->succ;
       curr->matricola=matricola;
       strcpy(curr->nome,nome);
       strcpy(curr->cognome,cognome);
       elemento=curr->puntatore;
       
      
       fscanf(fp,"%d", &settimane);// MI DEVO CREARE UN CICLO PER LE SOTTO STRUTTURE
      
     printf("%d %s %s\n",curr->matricola,curr->nome,curr->cognome);
       
   
       int giorni;
       int i;                      
       int z;
       
    elemento=(settimana*)malloc(sizeof(settimana));
       ricordo=elemento;
   
       for(z=0;z<settimane;z++){
      
   ricordo->succ=(settimana*)malloc(sizeof(settimana));
 
      
      fscanf(fp,"%d%d", &ricordo->succ->numero,&ricordo->succ->giorni);
      
     
     
      
      giorni=ricordo->succ->giorni;
       
       for(i=0;i<giorni;i++){
                                fscanf(fp,"%d",&ricordo->succ->ore[i]);
                                }
                                 
                                ricordo=ricordo->succ;
                ricordo->succ=NULL;
                               
      }
 //stampa
         for(z=0;z<settimane;z++){
         printf("\n%d %d ",elemento->succ->numero,elemento->succ->giorni);
       
       
       
       for(i=0;i<elemento->succ->giorni;i++){
                                printf("%d ", elemento->succ->ore[i]);
                                }
                                printf("\n");
       elemento=elemento->succ;
                                }
          
                                
}
       
      
       //devo vedere come fare per leggere il resto del file e mettere tutto nel posto giusto
      
       
       }
int main(void)
{
    FILE *fp;
 fp=fopen("prova.txt", "r");
 if(fp==NULL){
              printf("errore\n");
              return(0);
              }
 else{
      printf("file letto correttamente\n");
      }
    
      int i,a;
      fscanf(fp,"%d",&i); //letto il numero degli impigati
    //mi creo un vettore di puntatori di dimensione appropiata
      dipendenti *primo;
      primo=(dipendenti*)malloc (sizeof(dipendenti));
      primo->succ=NULL;
      primo->puntatore=NULL;
      
     
     
  crealista(fp, primo, i);
      
      
system("pause")  ;
}   
ho scambiato la funzione dei puntatori e adesso funziona!
wingman87
29-02-2008, 18:24
Così mi sembra corretto però hai uno spreco di memoria, cioè il primo elemento che hai creato non viene utilizzato se non per puntare al secondo (primo logicamente) elemento. 
Potresti fare una cosa di questo tipo:
elemento=(settimana*)malloc(sizeof(settimana));
ricordo=elemento;
   
for(z=0;z<settimane;z++){    
   fscanf(fp,"%d%d", &ricordo->numero,&ricordo->giorni);
   giorni=ricordo->giorni;
   for(i=0;i<giorni;i++){
      fscanf(fp,"%d",&ricordo->ore[i]);
   }
   if(z<settimane-1){
      ricordo->succ=(settimana*)malloc(sizeof(settimana));
      ricordo=ricordo->succ;
   }else{
      ricordo->succ=NULL;
   }                       
}
Poi dovresti riadattare anche la stampa.
PS: se settimane=0 elementi viene allocato lo stesso.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.