Repository 32bit  Forum
Repository 64bit  Wiki

problema con le "liste" [RISOLTO]

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

problema con le "liste" [RISOLTO]

Messaggioda Blallo » gio lug 30, 2009 1:44

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLAPFILE 20
#define MAXLN 80
#define MAXPLACE 3

typedef struct laps
{
   int lap;
   char lapfile[MAXLAPFILE];
}laps;

typedef struct readlap
{
   int drivenum;
   char drivename[MAXLAPFILE];
   char team[MAXLAPFILE];
   int laptime;
}readlap;

typedef struct pilot_t
{
   int lap;
   int drivenum;
   char drivename[MAXLAPFILE];
   char team[MAXLAPFILE];
   int laptime;
   struct pilot_t *next;
}pilot_t;

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head);
void print_fastest(pilot_t *head);
void print_three_bests(pilot_t *head);
pilot_t *take_out(pilot_t *head, char drivename);

int main()
{
   char fpIN[MAXLN];
   FILE *fp, *fp2;
   laps *tmp;
   pilot_t *head=NULL;

   printf("Inserire nome file input:");
   scanf("%s", fpIN);
   if((fp=fopen(fpIN,"r"))==NULL)//controllo apertura file
   {
      printf("Errore apertura file");
      return EXIT_FAILURE;
   }

   if((tmp=(laps *)malloc(sizeof(laps)))==NULL)//allocazione dinamica struct per primo file
   {
      printf("Errore allocazione memoria");
      return EXIT_FAILURE;
   }

   while(!feof(fp))
   {
      fscanf(fp, "%d %s", &(*tmp).lap,(* tmp).lapfile);
      if((fp2=fopen((*tmp).lapfile,"r"))==NULL)
      {
         printf("Errore apertura file");
         return EXIT_FAILURE;
      }
      while(!feof(fp2))
         head=charge_list((*tmp).lap, fp2, head);//caricamento lista
   }
   free(tmp);//rimozione struct primo file, è inutile dopo aver caricato la lista
   fclose(fp);//chiusura file, è inutile dopo aver caricato la lista
   fclose(fp2);//come sopra
   print_fastest(head);//giro più veloce
   print_three_bests(head);//tre piloti più veloci
    return EXIT_SUCCESS;
}

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head)//carica lista
{
   pilot_t *tmp;
   readlap tmplap;

   if((tmp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
   {
      printf("Errore allocazione memoria");
      exit(1);
   }

   fscanf(fp, "%d %s %s %d", &tmplap.drivenum, tmplap.drivename, tmplap.team, &tmplap.laptime);
   tmp->lap=lap;
   tmp->drivenum=tmplap.drivenum;
   strcpy(tmp->drivename, tmplap.drivename);
   strcpy(tmp->team, tmplap.team);
   tmp->laptime=tmplap.laptime;
   tmp->next=head;
   head=tmp;
   return head;
}

void print_fastest(pilot_t *head)//cerca e stampa a video il giro più veloce
{
   pilot_t *s, *t;

   s=head;
   t=head;

   while(s!=NULL)
   {
      if(s->laptime < t->laptime)
         t=s;
      s=s->next;
   }

   printf("Giro veloce: %s, %s, %d secondi, giro %d", t->drivename, t->team, t->laptime, t->lap);
}

void print_three_bests(pilot_t *head)
{
   pilot_t *s, *temp=NULL, *ctemp, *t;
   int i;

   s=head;
   while(s!=NULL && s->lap==1)//crea lista temporanea primo giro
   {
      if((ctemp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
      {
         printf("Errore allocazione memoria");
         exit(1);
      }
      ctemp->lap=s->lap;
      ctemp->drivenum=s->drivenum;
      strcpy(ctemp->drivename, s->drivename);
      strcpy(ctemp->team, s->team);
      ctemp->laptime=s->laptime;
      ctemp->next=temp;
      temp=ctemp;
      s=s->next;
   }
   
   t=temp;
   while(t!=NULL)//somma tempi complessivi
   {
      t->laptime=0;
      while(s!=NULL)
      {
         if(strcmp(s->drivename, t->drivename)==0)
            t->laptime+=s->laptime;
         s=s->next;
      }
      t=t->next;
   }

   s=temp;
   for(i=0;i<MAXPLACE;i++)
   {
      while(s!=NULL)//cerca il più piccolo
      {
         if(s->laptime < t->laptime)
            t=s;
         s=s->next;
      }
      printf("%d %s, %s, %d secondi", i+1, t->drivename, t->team, t->laptime);
      temp=take_out(temp, t->drivename);
   }
}

pilot_t *take_out(pilot_t *head, char drivename)
{
   pilot_t *s, *t;

   if(strcmp((*head).drivename, drivename)==0)
   {
      s=head;
      head=head->next;
      free(s);
   }
   else
   {
      s=head;
      while(s!=NULL)
         if(strcmp(drivename, (*s).drivename)==0)
         {
            t=s->next;
            free(s);
         }
   }
   return head;
}

questo programma legge da un primo file strutturato come nella struct laps, che contiene per ogni giro il nome di un file da aprire strutturato come la struct readlap.
Deve stampare a video il pilota più veloce in uno specifico giro e i tre piloti complessivamente più veloci..
mi da dei warning di troppo che credo siano la causa del segmentation fault che ottengo in esecuzione...
vi prego aiutatemi! [-o<
Ultima modifica di Blallo il lun ago 17, 2009 16:39, modificato 1 volta in totale.
Io sono il detective Arsenio Magret, e porto sempre la camicia TATUATA!
Avatar utente
Blallo
Packager
Packager
 
Messaggi: 3228
Iscritto il: ven ott 12, 2007 10:37
Località: Torino / Torremaggiore (FG)
Nome Cognome: Savino Liguori
Slackware: 14.1 / 12.2
Kernel: 3.12.2-ck
Desktop: Openbox

Re: problema liste aiuto!

Messaggioda kreen » gio lug 30, 2009 7:23

Ciao.
Ho fatto copia incolla e l'ho compilato. Non l'ho eseguito perche' non ho il file.

Codice: Seleziona tutto
venom@darkstar:~/tmp$ gcc -Wall -o code code.c
code.c: In function 'print_three_bests':
code.c:162: warning: passing argument 2 of 'take_out' makes integer from pointer without a cast
code.c: In function 'take_out':
code.c:170: warning: passing argument 2 of 'strcmp' makes pointer from integer without a cast
code.c:180: warning: passing argument 1 of 'strcmp' makes pointer from integer without a cast
code.c:187:6: warning: no newline at end of file



L'origine dei tuoi warning e' la funzione take_out.
Se vai a vedere la signature della funzione

Codice: Seleziona tutto
pilot_t *take_out(pilot_t *head, char drivename);


dichiari drivename come char e non char*.
Se ci pensi bene, adesso sai i segmentation fault da dove arrivano.

Buon lavoro,
ciao

PS. Non ho esaminato il codice, percio' non so se esiste qualcosa d'altro...
Avatar utente
kreen
Linux 2.4
Linux 2.4
 
Messaggi: 228
Iscritto il: mer feb 01, 2006 18:32
Località: Verona
Slackware: 12.0
Kernel: 2.6.21.5-smp
Desktop: KDE

Re: problema liste aiuto!

Messaggioda Blallo » gio lug 30, 2009 17:30

Ho migliorato e alleggerito di due struct il codice...e infatti mi esegue la function print_fastest, ma mi da un segmentation fault alla print_three_bests
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLAPFILE 20
#define MAXLN 80
#define MAXPLACE 3

typedef struct pilot_t
{
   int lap;
   int drivenum;
   char drivename[MAXLAPFILE];
   char team[MAXLAPFILE];
   int laptime;
   struct pilot_t *next;
}pilot_t;

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head);
void print_fastest(pilot_t *head);
void print_three_bests(pilot_t *head);
pilot_t *take_out(pilot_t *head, char drivename[MAXLAPFILE]);

int main()
{
   char fpIN[MAXLN], fpLAP[MAXLAPFILE];
   FILE *fp, *fp2;
   int lap;
   pilot_t *head=NULL;

   printf("Inserire nome file input:");
   scanf("%s", fpIN);
   if((fp=fopen(fpIN,"r"))==NULL)//controllo apertura file
   {
      printf("Errore apertura file");
      return EXIT_FAILURE;
   }

   while(!feof(fp))
   {
      fscanf(fp, "%d %s", &lap, fpLAP);
      if((fp2=fopen(fpLAP,"r"))==NULL)
      {
         printf("Errore apertura file");
         return EXIT_FAILURE;
      }
      while(!feof(fp2))
         head=charge_list(lap, fp2, head);//caricamento lista
   }
   fclose(fp);//chiusura file, è inutile dopo aver caricato la lista
   fclose(fp2);//come sopra
   print_fastest(head);//giro più veloce
   print_three_bests(head);//tre piloti più veloci
    return EXIT_SUCCESS;
}

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head)//carica lista
{
   pilot_t *tmp;

   if((tmp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
   {
      printf("Errore allocazione memoria");
      exit(1);
   }
   tmp->lap=lap;
   fscanf(fp, "%d %s %s %d", &tmp->drivenum, tmp->drivename, tmp->team, &tmp->laptime);
   tmp->next=head;
   head=tmp;
   return head;
}

void print_fastest(pilot_t *head)//cerca e stampa a video il giro più veloce
{
   pilot_t *s, *t;

   s=head;
   t=head;

   while(s!=NULL)
   {
      if(s->laptime < t->laptime)
         t=s;
      s=s->next;
   }

   printf("Giro veloce: %s, %s, %d secondi, giro %d\n", t->drivename, t->team, t->laptime, t->lap);
}

void print_three_bests(pilot_t *head)
{
   pilot_t *s, *temp=NULL, *ctemp, *t;
   int i;

   s=head;
   while(s!=NULL && s->lap==1)//crea lista temporanea primo giro
   {
      if((ctemp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
      {
         printf("Errore allocazione memoria");
         exit(1);
      }
      ctemp->lap=s->lap;
      ctemp->drivenum=s->drivenum;
      strcpy(ctemp->drivename, s->drivename);
      strcpy(ctemp->team, s->team);
      ctemp->laptime=s->laptime;
      ctemp->next=temp;
      temp=ctemp;
      s=s->next;
   }
   t=temp;
   while(t!=NULL)//somma tempi complessivi
   {
      t->laptime=0;
      while(s!=NULL)
      {
         if(strcmp(s->drivename, t->drivename)==0)
            t->laptime+=s->laptime;
         s=s->next;
      }
      t=t->next;
   }

   s=temp;
   for(i=0;i<MAXPLACE;i++)
   {
      while(s!=NULL)//cerca il più piccolo
      {
         if(s->laptime < t->laptime)
            t=s;
         s=s->next;
      }
      printf("%d %s, %s, %d secondi", i+1, t->drivename, t->team, t->laptime);
      temp=take_out(temp, t->drivename);//libera il primo pilota più veloce così che alla prossima ricerca cambi il minore, prendendo il secondo più piccolo
   }
}

pilot_t *take_out(pilot_t *head, char drivename[MAXLAPFILE])//sputa fuori
{
   pilot_t *s, *t;
   
   s=head;
   if(strcmp(s->drivename, drivename)==0)//rimozione in testa
   {
      head=head->next;
      free(s);
   }
   else
   {
      t=head->next;
      while(t!=NULL && (strcmp(t->drivename, drivename)!=0))
      {
         s=t;
         t=t->next;
      }
      
      s->next=t->next;
      free(t);
   }
   return head;
}
Io sono il detective Arsenio Magret, e porto sempre la camicia TATUATA!
Avatar utente
Blallo
Packager
Packager
 
Messaggi: 3228
Iscritto il: ven ott 12, 2007 10:37
Località: Torino / Torremaggiore (FG)
Nome Cognome: Savino Liguori
Slackware: 14.1 / 12.2
Kernel: 3.12.2-ck
Desktop: Openbox

Re: problema liste aiuto!

Messaggioda kreen » sab ago 01, 2009 12:16

Perche' non usi un debugger e non esamini cosa succede in quella funzione?

Secondo me sarebbe un utile pratica.

Ciao
Avatar utente
kreen
Linux 2.4
Linux 2.4
 
Messaggi: 228
Iscritto il: mer feb 01, 2006 18:32
Località: Verona
Slackware: 12.0
Kernel: 2.6.21.5-smp
Desktop: KDE

Re: problema liste aiuto!

Messaggioda Calzo » lun ago 03, 2009 21:08

Premesso che quello che suggerisce kreen è la cosa più saggia, secondo me nella funzione print_three_bests() continui a sovrascrivere le variabili perdendo anche pezzi della lista... ma l'ho letta molto velocemente quindi magari mi sbaglio.

bye
Avatar utente
Calzo
Linux 2.0
Linux 2.0
 
Messaggi: 112
Iscritto il: sab ott 06, 2007 21:21
Località: MN
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE

Re: problema liste aiuto!

Messaggioda Calzo » mar ago 04, 2009 22:10

Ciao
ho riletto meglio la funzione print_three_bests(). L'errore più grosso è quello del primo while dove controlli subito che s->lap sia pari a 1, ma per come costruisci la lista, ammenttendo che il rpimo file indichi il primo lap, questo while verrà saltato subito. Ho provato a riscriverla cancellando la funzione take_out(). Per liberare la memoria pensaci tu, comunque a me non ha dato più problemi, salvo che stampa semprelo stesso output per 3 volte. Ad ogni modo i segfault non li ho +.
Codice: Seleziona tutto
void print_three_bests(pilot_t *head)
    {
       pilot_t *s, *temp=NULL, *ctemp, *t;
       int i;

       s=head;
       while(s!=NULL)   //<-------------------------------
       {
          if(s->lap!=1)   //<-------------------------------
          {
             s=s->next;
             continue;
          }
          if((ctemp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
          {
             printf("Errore allocazione memoria\n");
             exit(1);
          }
          ctemp->lap=s->lap;
          ctemp->drivenum=s->drivenum;
          strcpy(ctemp->drivename, s->drivename);
          strcpy(ctemp->team, s->team);
          ctemp->laptime=s->laptime;
          ctemp->next=temp;
          temp=ctemp;
          s=s->next;
       }
       t=temp;
       while(t!=NULL)//somma tempi complessivi
       {
          t->laptime=0;
          s=head;    //<-------------------------------
          while(s!=NULL)
          {
             if(strcmp(s->drivename, t->drivename)==0)
                t->laptime+=s->laptime;
             s=s->next;
          }
          t=t->next;
       }

       t=temp;  //<-------------------------------
       s=temp;
       for(i=0;i<MAXPLACE;i++)
       {
          while(s!=NULL)//cerca il più piccolo
          {
             if(s->laptime < t->laptime)
                t=s;
             s=s->next;
          }
          printf("%d %s, %s, %d secondi\n", i+1, t->drivename, t->team, t->laptime); //<-------------------------------
          //temp=take_out(temp, t->drivename);
       }
    }

ho indicato con una freccia le righe che ho toccato.

bye
Avatar utente
Calzo
Linux 2.0
Linux 2.0
 
Messaggi: 112
Iscritto il: sab ott 06, 2007 21:21
Località: MN
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE

Re: problema con le "liste"

Messaggioda Blallo » lun ago 17, 2009 16:38

ciao a tutti
ho risolto così
Codice: Seleziona tutto
/*programma calcolo piloti - stupendo!!! - by Liguori Savino Pio*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLAPFILE 20
#define MAXLN 80
#define MAXPLACE 3

typedef struct pilot_t
{
   int lap;
   int drivenum;
   char drivename[MAXLAPFILE];
   char team[MAXLAPFILE];
   int laptime;
   struct pilot_t *next;
}pilot_t;

typedef struct pilot_bis
{
   char drivename[MAXLAPFILE];
   char team[MAXLAPFILE];
   int laptime;
   struct pilot_bis *next;
}pilot_bis;

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head);
void print_fastest(pilot_t *head);
void print_three_bests(pilot_t *head);
pilot_bis *take_out(pilot_bis *head, char drivename[MAXLAPFILE]);
void seek_and_destroy_one(pilot_t *head);
void seek_and_destroy_two(pilot_bis *head);

int main()
{
   char fpIN[MAXLN], fpLAP[MAXLAPFILE];
   FILE *fp, *fp2;
   int lap;
   pilot_t *head=NULL;

   printf("Inserire nome file input:");
   scanf("%s", fpIN);
   if((fp=fopen(fpIN,"r"))==NULL)//controllo apertura file
   {
      printf("Errore apertura file");
      return EXIT_FAILURE;
   }

   while(!feof(fp))
   {
      fscanf(fp, "%d %s", &lap, fpLAP);
      if((fp2=fopen(fpLAP,"r"))==NULL)
      {
         printf("Errore apertura file");
         return EXIT_FAILURE;
      }
      while(!feof(fp2))
         head=charge_list(lap, fp2, head);//caricamento lista
   }
   fclose(fp);//chiusura file, è inutile dopo aver caricato la lista
   fclose(fp2);//come sopra
   print_fastest(head);//giro più veloce
   print_three_bests(head);//tre piloti più veloci
   seek_and_destroy_one(head);//libera la memoria
    return EXIT_SUCCESS;
}

pilot_t *charge_list(int lap, FILE *fp, pilot_t *head)//carica lista
{
   pilot_t *tmp;

   if((tmp=(pilot_t *)malloc(sizeof(pilot_t)))==NULL)
   {
      printf("Errore allocazione memoria");
      exit(1);
   }
   tmp->lap=lap;
   fscanf(fp, "%d %s %s %d", &tmp->drivenum, tmp->drivename, tmp->team, &tmp->laptime);
   tmp->next=head;
   head=tmp;
   return head;
}

void print_fastest(pilot_t *head)//cerca e stampa a video il giro più veloce
{
   pilot_t *s, *t;

   s=head;
   t=head;

   while(s!=NULL)
   {
      if(s->laptime < t->laptime)
         t=s;
      s=s->next;
   }

   printf("Giro veloce: %s, %s, %d secondi, giro %d\n", t->drivename, t->team, t->laptime, t->lap);
}

void print_three_bests(pilot_t *head)
{
   pilot_t *s;
   pilot_bis *temp=NULL, *ctemp, *t, *t2;
   int i, ver;

   printf("Classifica piloti:\n");
   s=head;
   while(s!=NULL)//crea lista temporanea
   {
       t=temp;
      if(t==NULL)
      {
         if((ctemp=(pilot_bis *)malloc(sizeof(pilot_bis)))==NULL)
         {
            printf("Errore allocazione memoria");
            exit(1);
         }
         strcpy(ctemp->drivename, s->drivename);
         strcpy(ctemp->team, s->team);
         ctemp->laptime=s->laptime;
         ctemp->next=temp;
         temp=ctemp;
      }
      else
      {
         while(t!=NULL)
         {
            if(strcmp(t->drivename, s->drivename)==0)
            {
               ver=1;
               t->laptime+=s->laptime;
               break;
            }
            else
            {
               ver=0;
                    t=t->next;
            }
         }
         if(ver==0)
         {
            if((ctemp=(pilot_bis *)malloc(sizeof(pilot_bis)))==NULL)
            {
               printf("Errore allocazione memoria");
               exit(1);
            }
            strcpy(ctemp->drivename, s->drivename);
            strcpy(ctemp->team, s->team);
            ctemp->laptime=s->laptime;
            ctemp->next=temp;
            temp=ctemp;
         }
      }
      s=s->next;
   }

   for(i=0;i<MAXPLACE;i++)
   {
        t=temp;
        t2=temp;
      while(t2!=NULL)//cerca il più piccolo
      {
         if(t2->laptime < t->laptime)
            t=t2;
         t2=t2->next;
      }
      printf("%d %s, %s, %d secondi\n", i+1, t->drivename, t->team, t->laptime);
      temp=take_out(temp, t->drivename);//libera il primo pilota più veloce così che alla prossima ricerca cambi il minore, prendendo il secondo più piccolo
   }
   seek_and_destroy_two(temp);
}

pilot_bis *take_out(pilot_bis *head, char drivename[MAXLAPFILE])//sputa fuori
{
   pilot_bis *s, *t;
   
   s=head;

   if(strcmp(s->drivename, drivename)==0)//rimozione in testa
   {
      head=head->next;
      free(s);
   }
   else
   {
      t=head->next;
      while(t!=NULL && (strcmp(t->drivename, drivename)!=0))
      {
         s=t;
         t=t->next;
      }

      if(t!=NULL)
      {
          s->next=t->next;
            free(t);
      }
   }
   return head;
}

void seek_and_destroy_one(pilot_t *head)
{
   pilot_t *s;

   while(head!=NULL)
   {
      s=head;
      head=head->next;
      free(s);
   }
   head=NULL;
}

void seek_and_destroy_two(pilot_bis *head)
{
   pilot_bis *s;
   
   while(head!=NULL)
   {
      s=head;
      head=head->next;
      free(s);
   }
   head=NULL;
}

grazie mille a tutti per l'interessamento :D
Io sono il detective Arsenio Magret, e porto sempre la camicia TATUATA!
Avatar utente
Blallo
Packager
Packager
 
Messaggi: 3228
Iscritto il: ven ott 12, 2007 10:37
Località: Torino / Torremaggiore (FG)
Nome Cognome: Savino Liguori
Slackware: 14.1 / 12.2
Kernel: 3.12.2-ck
Desktop: Openbox


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite