Lettura da file con allocazione in una lista

di il
36 risposte

36 Risposte - Pagina 2

  • Re: Lettura da file con allocazione in una lista

    
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct articolo {
      int num;
      struct articolo *next;
    }nodo;
    
    void cons(int value, nodo **head)
    {
      nodo *new;
      int numero;
      
      if ((new=(nodo *)malloc(sizeof(nodo)))==NULL)
      {
        fprintf (stderr,"Cannont allocate\n");
        return ;
      }
      
      new->num=value;
    
      new->next=*head;
      
      *head=new;
      
    }
    
    void cancella (nodo **head)
    {
      nodo *tmp=*head,*next;
      while(tmp)
      {
        next=tmp->next;
        free (tmp);
        tmp=next;
      }
    }
    
    void stampa(nodo **head)
    {
      nodo *tmp=*head;
      while(tmp)
      {
        printf("%d--> ", tmp->num);
        tmp=tmp->next;
      }  
      printf("\n");
    }
    
    void legge (char *filename, nodo **head)
    {
      FILE *fp;
      int value;
      
      if ((fp=fopen (filename,"r"))==NULL)
      {
        fprintf (stderr,"Cannot open file %s\n",filename);
        return;
      }
      while (!feof(fp))
      {
        if (fscanf (fp,"%d",&value)>0)
          cons(value, head);    
      }
      fclose (fp);
    }
    int main ()
    {
      nodo *head=NULL;
      
      legge ("foo.txt",&head);
      stampa (&head);
      cancella (&head);
      return 0;
    }
    
    foo.txt
    
    12 24 36
    99
    -1
    
  • Re: Lettura da file con allocazione in una lista

    ixamit ha scritto:


    
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct articolo {
      int num;
      struct articolo *next;
    }nodo;
    
    void cons(int value, nodo **head)
    {
      nodo *new;
      int numero;
      
      if ((new=(nodo *)malloc(sizeof(nodo)))==NULL)
      {
        fprintf (stderr,"Cannont allocate\n");
        return ;
      }
      
      new->num=value;
    
      new->next=*head;
      
      *head=new;
      
    }
    
    void cancella (nodo **head)
    {
      nodo *tmp=*head,*next;
      while(tmp)
      {
        next=tmp->next;
        free (tmp);
        tmp=next;
      }
    }
    
    void stampa(nodo **head)
    {
      nodo *tmp=*head;
      while(tmp)
      {
        printf("%d--> ", tmp->num);
        tmp=tmp->next;
      }  
      printf("\n");
    }
    
    void legge (char *filename, nodo **head)
    {
      FILE *fp;
      int value;
      
      if ((fp=fopen (filename,"r"))==NULL)
      {
        fprintf (stderr,"Cannot open file %s\n",filename);
        return;
      }
      while (!feof(fp))
      {
        if (fscanf (fp,"%d",&value)>0)
          cons(value, head);    
      }
      fclose (fp);
    }
    int main ()
    {
      nodo *head=NULL;
      
      legge ("foo.txt",&head);
      stampa (&head);
      cancella (&head);
      return 0;
    }
    
    foo.txt
    
    12 24 36
    99
    -1
    

    ok, e se volessi sempre il mio codice e lo volessi aggiustare da li? Cosa sbaglio nel mio codice, questo è quello che non mi faccio convinto. Perchè se copio il codice che mi hai scritto non imparo l'errore.

    Ti ringrazio tantissimo, mi sei davvero di grande aiuto. Peccato però che sei tu solo a rispondermi.
  • Re: Lettura da file con allocazione in una lista

    Non voglio mettermi con carta e penna a seguire la tua logica nella lista ma:
    1) nel main allochi un blocco senza inserire niente.
    2) non deallochi i blocchi allocati alla fine del main
    3) non capisco start, p e punt

    Io al posto tuo cercherei di partire da un esempio corretto quale può essere quello presentato qui oppure puoi trovare maggiori informazioni su wikipedia:

    non cercare di correggere qualcosa impostato male all'origine... poi vedi tu..
    anche perchè quando poi andrai ad aggiungere una struttura alla lista la modifica in questo caso è lieve, mentre nel tuo src deve essere radicale

    ~Max
  • Re: Lettura da file con allocazione in una lista

    E' tutto il pomeriggio che provo. Quello che mi rode e che mi sta facendo saltare il cervello è che il file lo legge, però non vuole allocare ogni singolo numero dentro ogni elemento-lista.
    Infatti quando carico i numeri scritti nel file, mi alloca nella lista SOLO l'ultimo numero.
    Questo è il mio problema. Nel ciclo "while(!feof(pf))" mi scorre tutto senza bisogno di incrementi, e quindi non riesco a controlllare i singoli numeri, ma mi arrivano tutti insieme e riesco a cogliere solo l'ultimo.
    La domanda è: COME POSSO RICEVERE I NUMERI POSTI DENTRO AL FILE AD UNO AD UNO???
  • Re: Lettura da file con allocazione in una lista

    ixamit ha scritto:


    Non voglio mettermi con carta e penna a seguire la tua logica nella lista ma:
    1) nel main allochi un blocco senza inserire niente.
    2) non deallochi i blocchi allocati alla fine del main
    3) non capisco start, p e punt

    Io al posto tuo cercherei di partire da un esempio corretto quale può essere quello presentato qui oppure puoi trovare maggiori informazioni su wikipedia:

    non cercare di correggere qualcosa impostato male all'origine... poi vedi tu..
    anche perchè quando poi andrai ad aggiungere una struttura alla lista la modifica in questo caso è lieve, mentre nel tuo src deve essere radicale

    ~Max
    1) Nel main alloco un blocco da solo, dove ci attacco tutta la lista, col puntatore START.
    2) Come si deallocano i blocchi alla fine del main?? A cosa mi serve?
    3) Start è il puntatore al blocco, p è un puntatore che punta a start per non perdere la lista, punt è sbagliato, lo devo cancellare.
  • Re: Lettura da file con allocazione in una lista

    1) Nel main alloco un blocco da solo, dove ci attacco tutta la lista, col puntatore START.
    Se inserisci 3 numeri devi allocare 3 blocchi. Il blocco in questione non serve a nulla e per giunta num puo' contenere qualsiasi valore
    2) Come si deallocano i blocchi alla fine del main?? A cosa mi serve?
    La memoria allocata tramite malloc è persistente: ciò significa che continuerà ad esistere fino alla fine del programma o fino a quando non sarà esplicitamente deallocata dal programmatore (detto anche "liberata"). Questo risultato è ottenuto tramite la funzione free
    3) Start è il puntatore al blocco, p è un puntatore che punta a start per non perdere la lista, punt è sbagliato, lo devo cancellare.
    dunque start è il puntatore al primo blocco... e gli altri ptr non servono a nulla

    Questo è il mio problema. Nel ciclo "while(!feof(pf))" mi scorre tutto senza bisogno di incrementi, e quindi non riesco a controlllare i singoli numeri, ma mi arrivano tutti insieme e riesco a cogliere solo l'ultimo.
    
    nodo *leggi(nodo *start, nodo *p)
       {FILE *pf; 
        pf=fopen("numeri.txt", "r");
        nodo *start3;
        start3=(nodo *)malloc(sizeof(nodo)); 
        p=start3;
    
        if(pf)
          {while(!feof(pf))
             {fscanf(pf, "%d\t", &p->num); p=p->next;} 
           fclose(pf);
          }else{printf("Errore nella lettura del file\n");}
       p->next=start;
       return(start3);   } 
    
    Infatti, il file viene letto sequenzialmente e ad ogni fscanf ti carica il valore nella struttura... ma tu devi inserire ogni singola struttura nella lista e questo non lo stai facendo
  • Re: Lettura da file con allocazione in una lista

    ixamit ha scritto:


    1) Nel main alloco un blocco da solo, dove ci attacco tutta la lista, col puntatore START.
    Se inserisci 3 numeri devi allocare 3 blocchi. Il blocco in questione non serve a nulla e per giunta num puo' contenere qualsiasi valore
    2) Come si deallocano i blocchi alla fine del main?? A cosa mi serve?
    La memoria allocata tramite malloc è persistente: ciò significa che continuerà ad esistere fino alla fine del programma o fino a quando non sarà esplicitamente deallocata dal programmatore (detto anche "liberata"). Questo risultato è ottenuto tramite la funzione free
    3) Start è il puntatore al blocco, p è un puntatore che punta a start per non perdere la lista, punt è sbagliato, lo devo cancellare.
    dunque start è il puntatore al primo blocco... e gli altri ptr non servono a nulla

    Questo è il mio problema. Nel ciclo "while(!feof(pf))" mi scorre tutto senza bisogno di incrementi, e quindi non riesco a controlllare i singoli numeri, ma mi arrivano tutti insieme e riesco a cogliere solo l'ultimo.
    
    nodo *leggi(nodo *start, nodo *p)
       {FILE *pf; 
        pf=fopen("numeri.txt", "r");
        nodo *start3;
        start3=(nodo *)malloc(sizeof(nodo)); 
        p=start3;
    
        if(pf)
          {while(!feof(pf))
             {fscanf(pf, "%d\t", &p->num); p=p->next;} 
           fclose(pf);
          }else{printf("Errore nella lettura del file\n");}
       p->next=start;
       return(start3);   } 
    
    Infatti, il file viene letto sequenzialmente e ad ogni fscanf ti carica il valore nella struttura... ma tu devi inserire ogni singola struttura nella lista e questo non lo stai facendo
    Ok,
    domande:
    1) Io non so i valori che devo aggiungere, creo la funzione di aggiunta in testa, comunemente chiamata cons. Se non creo un punto dove attaccare la lista la perdo. Quindi ho creato un'allocazione con la testa, chiamato start. Come dovrei fare per farlo come mi hai spiegato tu?
    2) Per deallocare untilizzo il free, ok, se faccio free(start) mi libera tutta la lista, giusto??
    3)start è il puntatore al primo blocco, più correttamente lo chiamerei testa. Se ad esempio volessi stampare, o inserire un dato dentro l'allocazione, io perderei tutta la lista, infatti creo un altro puntatore *p che, anche se lo scorro tutto o lo utilizzo per inserire i dati, non mi fa perdere la lista.
    Come potrei fare con il solo start? Mi potresti dare una mano a creare tutto questo programma in modo corretto??


    Perdonami se ti faccio tutte queste domande, o se ti assillo sulle cose, è che tra 4 giorni ho un esame e quindi devo conoscere benissimo tutto. Ti ringrazio tantissimo, sei di grandissimo aiuto!! Grazie!


    Il testo di ttutto l'esercizio vuole che io gestica un magazzino, la struttura deve contenere solo una stringa di char che indica il nome, e un int che indica la quantità dei pezzi. Ci devono essere le funzioni aggiungi pezzo, aggiorna le quantità del pezzo(preleva o aggiungi pezzo), cerca, elimina, stampa, rimuovi tutto, carica da file, salva su file. Dopo ogni operazione che faccio deve aggiornare i valori relativi al numero di tipi di ricambi e al numero complessivo di pezzi presenti.


    Esempio:
    A)ggiungi, C)erca, E)limina, R)imuovi tutto, P)releva, D)eposita, C)arica, S)crivi, E)sci.
    p
    Quale tipo di ricambio vuoi prelevare? Ruota
    numero dei pezzi disponibili: 15
    quanti pezzi vuoi prelevare? 3






    PS: Per copiare un char dentro a un elemento della lista si utilizza la strcpy. Come si utilizza??? Io ho scritto strcpy("pippo", start->nome); ma non mi è funzionato. E' giusto???
  • Re: Lettura da file con allocazione in una lista

    Se non sai quanti dati devi leggere allora non allocare un nodo se prima non hai letto i dati che devono essere inseriti in essa. Quindi prima leggi il dato in una variabile temporanea e poi se la lettura è riuscita puoi copiare il dato in un nodo nuovo.

    p.s.: Se leggessi un pò di più l'uso delle funzioni capiresti che stai usando male la strcpy.

    http://www.cplusplus.com/reference/clibrary/cstring/strcpy/
    
    char * strcpy ( char * destination, const char * source );
    
    La prima è destination, la seconda è source. Tu lo stai usando al contrario.
  • Re: Lettura da file con allocazione in una lista

    Io lo sto usando così, ma non funziona:


    scanf("%s", nom_prod);
    strcpy(start2->nome, nom_prod);
  • Re: Lettura da file con allocazione in una lista

    Pongo la domanda precisa:
    Come faccio ad inserire un nome(cioè una stringa di char) dentro a un'allocazione di una lista chiamata start2->nome????????


    Non mi funziona nemmeno se scrivo:

    start2->nome="pippo";
  • Re: Lettura da file con allocazione in una lista

    Definire non funzia.
    
    typedef struct
    {
          char *nome;
          int quantita;
    }nodo;
    
    int main()
    {
       char temp[100];
       int quantita;
       scanf("%s",temp);
       nodo *nuovo = (nodo*)malloc(sizeof(nodo));
       if(nuovo != NULL)
       {
          nuovo->nome = (char *)malloc(sizeof(char) * (strlen(temp) + 1));
          strcpy(nuovo->nome,temp);
          scanf("%d",&quantita);
          nuovo->quantita = quantita;
    
    
        printf("%s - %d",nuovo->nome,nuovo->quantita);
        free(nuovo);
       }
    
    
    }
    
    
    così funziona.
  • Re: Lettura da file con allocazione in una lista

    Ho provato a creare la funzuione cons(cioè la funzione aggiungi in testa) senza allocare uno spazio vuoto ma non funziona, perchè come faccio a dire che attacco la lista alla testa start e alla fine ci deve essere null???
    
    {char sc;
    
    nodo *start;
    /* start=(nodo *)malloc(sizeof(nodo));
    start->next=NULL;
    */
    while(sc!='q')
    {sc=menu();
    switch(sc){
            case 'a': start=cons(start);    break;
           }
    
    nodo *cons(nodo *start)
            {char *nom_prod; int quant;  nodo *start2;
             start2=(nodo *)malloc(sizeof(nodo));
             start2->next=start;
    /*      printf("Inserisci Nome prodotto: ");
            scanf("%s", nom_prod);                   */
            printf("Inserisci la quantità: ");
            scanf("%d", &quant);
             start2->q=quant;
    
    /*       strcpy(start2->nome, nom_prod);  */
    
             return (start2);
            }
    
    
    
  • Re: Lettura da file con allocazione in una lista

    Mi stampa un numero che è allocato in memoria, oppure se alloco uno spazio vuoto mi stampa lo zero. Come faccio a fare il tutto senza problemi?
  • Re: Lettura da file con allocazione in una lista

    Puoi fare un programma togliendo le parti commentate. Così non si capisce niente. Se puoi metti un programma completo e non solo pezzi.
  • Re: Lettura da file con allocazione in una lista

    skynet ha scritto:


    Puoi fare un programma togliendo le parti commentate. Così non si capisce niente. Se puoi metti un programma completo e non solo pezzi.
    Ok.
    Questo è il codice del programma che ho utilizzato fin'ora, di cui ho 3 preblemi:
    1) non so come si fa ad inserire un nome\stringa in un'allocazione di memoria;
    2) non riesco a far leggere da file;
    3) quando stampo, mi stampa sempre lo zero alla fine.
    
    #include <stdio.h>
    #include <stdlib.h>
    struct articolo{ int num;
    		 struct articolo *next;		};	
    typedef struct articolo nodo;
    nodo *cons(nodo *start, nodo *p); 
    char menu();
    void stampa(nodo *start, nodo *p);
    nodo *delete(nodo *start, nodo *p);
    nodo *leggi(nodo *start, nodo *p);
    void scrivi(nodo *start, nodo *p);
    
    main(int argc, char **argv)
    {
    	char sc;
    	nodo *start, *p;
    
    	start=(nodo *)malloc(sizeof(nodo));
    
    	p=start; 
    	start->num=0;
    	p->next=NULL;  
    while(sc!='q'){
    sc=menu(); 
    switch(sc){
    	case 'a': start=cons(start, p);		 break; 
    	case 'd': start=delete(start, p);	 break;
    
    	case 'l': start=leggi(start, p);         break;
    	case 'w': scrivi(start, p); 	 	 break;
    	case 's': stampa(start, p);		 break;
    	case 'q': exit (0); }
    
    }
    }
    
    
    
    void stampa(nodo *start, nodo *p){
    	while(start!=NULL)
    	{printf("%d--> ", start->num);
    	 start=start->next;
    				}  
    	printf("\n");
    				}
    
    
    nodo *cons(nodo *start, nodo *p)
    	{ nodo *start2;  int numero;
    	 start2=(nodo *)malloc(sizeof(nodo));
    	printf("Inserisci numero: "); scanf("%d", &numero);
    	p=start2;	
    	p->num=numero;
    
    	p->next=start ; 
    	return (start2);
    	}
    
    
    char menu() 
    
    	{char sc; printf("A)dd, D)elete, S)tampa, L)oad, W)rite, Q)uit\n");
    	 scanf("%c", &sc); return (sc);	}
    
    nodo *delete(nodo *start, nodo *p)
    	{int num_del; nodo *p2; 
    	 printf("Inserisci il numero che vuoi eliminare:");
    	 scanf("%d", &num_del);
    	p2=start;
    	while(p2->next->num!=num_del)
    	{p2=p2->next;} 
    	p2->next=p2->next->next;	
    		return (start);  
    							}
    nodo *leggi(nodo *start, nodo *p)
    	{nodo *start3;
    	start3=(nodo *)malloc(sizeof(nodo)); 
    	p=start3;
    
    	FILE *pf;
    	pf=fopen("numeri.txt", "r");
    	 if(pf)
    		{while(!feof(pf))
    			{fscanf(pf, "%d\t", &p->num); p->next=start;  } 
    		fclose(pf);  
    		}else{printf("Errore nella lettura del file\n");}
    /* 	p->next=start;  */ 
    	return(start3);	} 
    
    void scrivi(nodo *start, nodo *p)
    	{FILE *pf;
    	 pf=fopen("numeri.txt", "w");
    	 if(pf)
    		{while(start!=NULL)
    			{fprintf(pf, "%d\t", start->num); start=start->next;}
    		fclose(pf);
    		}else{printf("Non è stato possibile scrivere il file\n");} 
    	} 
    


    Dato che il programma precedentemente citato è un pò incasinato, ho avuto la brillante idea di crearne un'altro, che ha gli stessi identici problemi, anche se è un pò meno incasinato:
    
    #include <stdio.h>
    #include <stdlib.h>
    struct articolo{ char nome[20];
    		 int q;
    		 struct articolo *next;};  
    typedef struct articolo nodo; 
    char menu();
    nodo *cons(nodo *start);
    void stampa(nodo *start);
    
    main(int argc, char **argv)
    {char sc; 
    
    nodo *start; /*
    start=(nodo *)malloc(sizeof(nodo));
    
    
    start->next=NULL;
    */
     
    while(sc!='q')
    {sc=menu();
    switch(sc){
    	case 'a': start=cons(start);	break;
    	case 'd': break;
    	case 's': stampa(start); 	break;
    	case 't': break;
    	case 'p': break;
    	case 'i': break;
    	case 'l': break;
    	case 'w': break;
    	case 'q': exit (0); break;
    	}}
    }
    
    
    
    char menu()
    	{char sc;
    	 printf("A)dd, D)elete, S)tampa, T)rova, P)relievo, I)nserisci, L)oad, W)rite, Q)uit.\n"); scanf("%c", &sc); return (sc); 
    	}
    
    nodo *cons(nodo *start) 
    	{char *nom_prod; int quant;  nodo *start2; 
    	 start2=(nodo *)malloc(sizeof(nodo));
    	 start2->next=start; 
    /*	printf("Inserisci Nome prodotto: ");	
    	scanf("%s", nom_prod); 			 */
    	printf("Inserisci la quantità: ");
    	scanf("%d", &quant); 
    	 start2->q=quant;
    
    /*	 strcpy(start2->nome, nom_prod);  */ 
    
    	 return (start2); 
    	}
    
    void stampa(nodo *start)
    	{while(start!=NULL)
    		{/* printf("%s", start->nome); */ 
    		 printf("%d\n", start->q); start=start->next;}  
    
    	} 
    

    PS: Le parti inserite tra /* */ sono le parti che secondo il mio raggionamento sono esatte, ma purtroppo mi creano errori e non funzionano.



    Grazie
Devi accedere o registrarti per scrivere nel forum
36 risposte