Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [C] Aiuto lista

  1. #1

    [C] Aiuto lista

    Traccia esercizio: Simulare in C la gestione delle camere di un albergo mediante liste lineari rappresentate su un array di struct: i principali campi sono le “informazioni” (numero di camera, cliente, etc.) ed i “link” (puntatori ai nodi della lista). [Suggerimento: L’array di struct corrisponde alla memoria in cui allocare la lista delle camere libere (ListaLibera) e la lista delle camere occupate (ListaDati). È necessario creare prima la ListaLibera, inizializzando l’array dei link in modo che ogni componente punti alla componente successiva. Ogni nodo da inserire nella ListaDati, quando una camera viene assegnata ad un cliente, è prelevato dalla testa della ListaLibera ed inserito nella testa della ListaDati; mentre il nodo da eliminare dalla ListaDati, quando una particolare camera viene liberata, è restituito alla ListaLibera (in testa) per poter essere riutilizzato in seguito.]

    Il programma funziona bene, l'unico problema sorge quando elimino l'ultimo elemento della lista e successivamente voglio inserirne un altro. Secondo me il problema è nella function libera ma non capisco come posso risolvere.


    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct
    {
        int n;
        char nome[20];
    }inf;
    struct listalibera
    {
        inf info;
        struct listalibera *next;
    };
    struct listadati
    {
         inf info;
        struct listadati *next;
    };
    typedef struct listalibera l_list;
    typedef struct listadati d_list;
    void ins_testa(d_list **d, l_list **l)
    {
        d_list *nuovo;
        nuovo=calloc(1,sizeof(d_list));
        nuovo->info.n=(*l)->info.n;
        printf("Stanza numero %d\n",nuovo->info.n);
        puts("Inserisci nome cliente: ");
        fflush(stdin);
        gets(nuovo->info.nome);
        nuovo->next=*d;
        *d=nuovo;
        l_list *l_t;
        l_t=(*l)->next;
        free(*l);
        *l=l_t;
    }
    void crea_l_t(l_list **testa)
    {
        l_list *h;
        h=calloc(1,sizeof(l_list));
        h->info.n=1;
        h->next=*testa;
        *testa=h;
    }
    void crea_l(l_list **pnt)
    {
        l_list *nuovo;
        int i;
        for(i=2;i<21;i++)
        {
            nuovo=calloc(1,sizeof(l_list));
            nuovo->info.n=i;
            nuovo->next=(*pnt)->next;
            (*pnt)->next=nuovo;
            *pnt=nuovo;
        }
        nuovo->next=NULL;
    }
    
    void ins_mezzo(d_list **pnt, l_list **l_h)
    {
        d_list *nuovo;
        nuovo=calloc(1,sizeof(d_list));
        nuovo->info.n=(*l_h)->info.n;
        printf("Stanza numero %d\n",nuovo->info.n);
        puts("Inserisci nome cliente: ");
        fflush(stdin);
        gets(nuovo->info.nome);
        nuovo->next=(*pnt)->next;
        (*pnt)->next=nuovo;
        *pnt=nuovo;
        l_list *temp;
        temp=(*l_h)->next;
        free(*l_h);
        *l_h=temp;
    }
    void libera(d_list **d, l_list **l)
    {
        d_list *temp;
        l_list *h;
        int n;
        temp=*d;
        puts("Quale camera devi liberare?");
        printf("La numero ");
        scanf("%d",&n);
        while(temp->info.n!=n)
        {
            temp=temp->next;
        }
        h=calloc(1,sizeof(l_list));
        h->info.n=temp->info.n;
        h->next=*l;
        *l=h;
        d_list *cur, *prev;
        for(cur=*d, prev=NULL; cur!=NULL && cur->info.n!=n; prev=cur, cur=cur->next);
        prev->next=cur->next;
        free(cur);
    }
    void libera_t(d_list **d, l_list **l)
    {
        l_list *h;
        d_list *temp;
        temp=*d;
        h=calloc(1,sizeof(l_list));
        h->info.n=temp->info.n;
        h->next=*l;
        *l=h;
        temp=(*d)->next;
        free(*d);
        *d=temp;
    }
    void visualizza_d(d_list *d)
    {
        if(d==NULL)
            puts("Non ci sono capere occupate.");
        else
        {
            puts("Camere occupate:");
            while(d!=NULL)
            {
                printf("Numero camera: %d\n",d->info.n);
                printf("Nome cliente: %s\n", d->info.nome);
                d=d->next;
            }
        }
    }
    void visualizza_l(l_list *l)
    {
        if(l==NULL)
            puts("Non ci sono capere libere.");
        else
        {
            puts("Camere occupate:");
            while(l!=NULL)
            {
                printf("Numero camera: %d\n",l->info.n);
                l=l->next;
            }
        }
    }
    
    int main()
    {
        l_list *l_head, *l_punt;
        d_list *d_head, *d_punt;
        l_head=NULL;
        d_head=NULL;
        l_punt=calloc(1,sizeof(l_list));
        crea_l_t(&l_head);
        l_punt=l_head;
        crea_l(&l_punt);
        int sc;
        while(sc!=6)
        {
            puts("Menu':\n1) Occupa stanza\n2) Libera stanza\n3) Visualizza camere occupate.\n4) Visualizza camere libere.\n5) Termina programma.");
            scanf("%d",&sc);
            switch(sc)
             {
                 case 1: if(d_head==NULL){
                                ins_testa(&d_head,&l_head);
                                d_punt=d_head;
                                }
                            else
                                ins_mezzo(&d_punt,&l_head);
                             break;
                 case 2 : if(d_head->next!=NULL)
                                libera(&d_head, &l_head);
                              else
                                libera_t(&d_head, &l_head);
                 break;
                 case 3 : visualizza_d(d_head);
                 break;
                 case 4: visualizza_l(l_head);
             }
        }
        return 0;
    }

  2. #2
    Utente di HTML.it L'avatar di filips
    Registrato dal
    Sep 2011
    residenza
    Seconda stella a destra (questo e' il cammino)
    Messaggi
    155
    Purtroppo sono al cellulare e non posso controllare niente, ma a occhio mi sembra che ci sia un problema logico nel blocco for di libera.
    Per fare un tavolo ci vuole un fiore.

  3. #3
    Quote Originariamente inviata da filips Visualizza il messaggio
    Purtroppo sono al cellulare e non posso controllare niente, ma a occhio mi sembra che ci sia un problema logico nel blocco for di libera.
    capito, quando puoi fammi sapere ^^

  4. #4
    Utente di HTML.it L'avatar di filips
    Registrato dal
    Sep 2011
    residenza
    Seconda stella a destra (questo e' il cammino)
    Messaggi
    155
    Sto provando il programma. Intanto ti dico che il menu "Visualizza camere occupate" ha qualche incoerenza, infatti se inserisco 2 nomi e poi visualizzo, ottengo questo:

    Camere occupate:
    Numero camera: 1
    Nome cliente:
    Numero camera: 2
    Nome cliente: enzo
    Numero camera: 3
    Nome cliente: pino


    Quando le camere occupate sono solo la 1 e la 2.
    Per fare un tavolo ci vuole un fiore.

  5. #5
    Quote Originariamente inviata da filips Visualizza il messaggio
    Sto provando il programma. Intanto ti dico che il menu "Visualizza camere occupate" ha qualche incoerenza, infatti se inserisco 2 nomi e poi visualizzo, ottengo questo:

    Camere occupate:
    Numero camera: 1
    Nome cliente:
    Numero camera: 2
    Nome cliente: enzo
    Numero camera: 3
    Nome cliente: pino


    Quando le camere occupate sono solo la 1 e la 2.
    guarda l'ho provato parecchie volte e non mi è mai successo

  6. #6
    Utente di HTML.it L'avatar di filips
    Registrato dal
    Sep 2011
    residenza
    Seconda stella a destra (questo e' il cammino)
    Messaggi
    155
    Così sembra funzionare.. ti lascio ragionare sulla base del codice per trovare l'errore logico, per vendetta, visto che io mi sono dovuto concentrare abbastanza per ricostruire il meccanismo che hai utilizzato (della serie: qualche commento sarebbe stato ben accetto :-)

    [notare che ho dovuto modificare le parti di input/output del tipo puts; fflush(stdin); gets(nuovo->info.nome); perche il compilatore che uso - gcc - le deprecava, e praticamente falliva l'esecuzione (v. output d'esempio che avevo postato)]

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct
    {
        int n;
        char nome[20];
    }inf;
    
    struct listalibera
    {
        inf info;
        struct listalibera *next;
    };
    
    struct listadati
    {
         inf info;
        struct listadati *next;
    };
    
    typedef struct listalibera l_list;
    typedef struct listadati d_list;
    
    void ins_testa(d_list **d, l_list **l)
    {
        d_list *nuovo;
        char s[20];
        nuovo=calloc(1,sizeof(d_list));
        nuovo->info.n=(*l)->info.n;
        printf("Stanza numero %d\n",nuovo->info.n);
        printf("Inserisci nome cliente: ");
        scanf("%s",s);
        int u;
    for (u=0;u<20;u++) {
        nuovo->info.nome[u] = s[u];
    }
        //fflush(stdin);
        //gets(nuovo->info.nome);
        nuovo->next=*d;
        *d=nuovo;
        l_list *l_t;
        l_t=(*l)->next;
        free(*l);
        *l=l_t;
    }
    
    void crea_l_t(l_list **testa)
    {
        l_list *h;
        h=calloc(1,sizeof(l_list));
        h->info.n=1;
        h->next=*testa;
        *testa=h;
    }
    
    void crea_l(l_list **pnt)
    {
        l_list *nuovo;
        int i;
        for(i=2;i<21;i++)
        {
            nuovo=calloc(1,sizeof(l_list));
            nuovo->info.n=i;
            nuovo->next=(*pnt)->next;
            (*pnt)->next=nuovo;
            *pnt=nuovo;
        }
        nuovo->next=NULL;
    }
    
    void ins_mezzo(d_list **pnt, l_list **l_h)
    {
        d_list *nuovo;
        char s[20];
        nuovo=calloc(1,sizeof(d_list));
        nuovo->info.n=(*l_h)->info.n;
        printf("Stanza numero %d\n",nuovo->info.n);
            printf("Inserisci nome cliente: ");
        scanf("%s",s);
        int u;
    for (u=0;u<20;u++) {
        nuovo->info.nome[u] = s[u];
    }
    //fflush(stdin);
        //gets(nuovo->info.nome);
    
        nuovo->next=(*pnt)->next;
        (*pnt)->next=nuovo;
        *pnt=nuovo;
        l_list *temp;
        temp=(*l_h)->next;
        free(*l_h);
        *l_h=temp;
    }
    
    void libera(d_list **d, l_list **l, d_list **dp)
    {
    
      d_list *temp;
        l_list *h;
        int n;
        temp=*d;
     
        puts("Quale camera devi liberare?");
        printf("La numero ");
        scanf("%d",&n);
        while(temp->info.n!=n)
        {
            temp=temp->next;
        }
    
        h=calloc(1,sizeof(l_list));
        h->info.n=temp->info.n;
        h->next=*l;
        *l=h;
        d_list *cur, *prev;
    
        for (cur=*d, prev=NULL; cur!=NULL && cur->info.n!=n; prev=cur, cur=cur->next);
      
    prev->next=cur->next;
    
    *dp=prev;
    free(cur);
    }
    
    void libera_t(d_list **d, l_list **l)
    {
    
        l_list *h;
        d_list *temp;
        temp=*d;
        h=calloc(1,sizeof(l_list));
        h->info.n=temp->info.n;
        h->next=*l;
        *l=h;
        
        temp=(*d)->next;
        free(*d);
        *d=temp;
    }
    
    void visualizza_d(d_list *d)
    {
        if(d==NULL)
            puts("Non ci sono capere occupate.");
        else
        {
            puts("Camere occupate:");
            while(d!=NULL)
            {
                printf("Numero camera: %d\n",d->info.n);
                printf("Nome cliente: %s\n", d->info.nome);
                d=d->next;
            }
        }
    }
    
    void visualizza_l(l_list *l)
    {
        if(l==NULL)
            puts("Non ci sono capere libere.");
        else
        {
            puts("Camere occupate:");
            while(l!=NULL)
            {
                printf("Numero camera: %d\n",l->info.n);
                l=l->next;
            }
        }
    }
    
    int main()
    {
        l_list *l_head, *l_punt;
        d_list *d_head, *d_punt;
        l_head=NULL;
        d_head=NULL;
        l_punt=calloc(1,sizeof(l_list));
        crea_l_t(&l_head);
        l_punt=l_head;
        crea_l(&l_punt);
        int sc;
        while(sc!=5)
        {
            puts("Menu':\n1) Occupa stanza\n2) Libera stanza\n3) Visualizza camere occupate.\n4) Visualizza camere libere.\n5) Termina programma.");
            scanf("%d",&sc);
            switch(sc)
             {
                 case 1: if(d_head==NULL){
                                ins_testa(&d_head,&l_head);
                                d_punt=d_head;
                                }
                            else
                                ins_mezzo(&d_punt,&l_head);
                             break;
                 case 2 : if(d_head->next!=NULL)
                                libera(&d_head, &l_head, &d_punt);
                              else
                                libera_t(&d_head, &l_head);
                 break;
                 case 3 : visualizza_d(d_head);
                 break;
                 case 4: visualizza_l(l_head);
             }
        }
        return 0;
    }
    Ultima modifica di filips; 05-09-2016 a 07:42
    Per fare un tavolo ci vuole un fiore.

  7. #7
    Quote Originariamente inviata da filips Visualizza il messaggio
    Così sembra funzionare.. ti lascio ragionare sulla base del codice per trovare l'errore logico, per vendetta, visto che io mi sono dovuto concentrare abbastanza per ricostruire il meccanismo che hai utilizzato (della serie: qualche commento sarebbe stato ben accetto :-)

    [notare che ho dovuto modificare le parti di input/output del tipo puts; fflush(stdin); gets(nuovo->info.nome); perche il compilatore che uso - gcc - le deprecava, e praticamente falliva l'esecuzione (v. output d'esempio che avevo postato)]
    Scusami, non ci avevo proprio pensato di inserire le note. Comunque era un errore stupido e più o meno avevo capito che dovevo aggiornare il puntatore. Grazie mille ^^

  8. #8
    Comunque ho modificato ancora la funzione libera perché se inserivo più elementi e poi volevo eliminare la testa giustamente crashava. Ho creato una variabile m nel main passata per indirizzo a libera. Nella funzione libera controlla se prev==NULL. Se è vero m diventa uguale ad 1 e la funzione finisce. Ritornati al main vede se m è uguale ad 1, se è uguale si va alla funzione libera_t (per liberare la testa). Quando si ritorna nel main m diventa uguale a 0.

  9. #9
    Utente di HTML.it L'avatar di filips
    Registrato dal
    Sep 2011
    residenza
    Seconda stella a destra (questo e' il cammino)
    Messaggi
    155
    Quote Originariamente inviata da thefiery77 Visualizza il messaggio
    Comunque ho modificato ancora la funzione libera perché se inserivo più elementi e poi volevo eliminare la testa giustamente crashava. Ho creato una variabile m nel main passata per indirizzo a libera. Nella funzione libera controlla se prev==NULL. Se è vero m diventa uguale ad 1 e la funzione finisce. Ritornati al main vede se m è uguale ad 1, se è uguale si va alla funzione libera_t (per liberare la testa). Quando si ritorna nel main m diventa uguale a 0.
    Perfetto, ora direi che è a posto. In effetti non avevo testato sulla testa ed è ovvio che col codice dato si abbia il crash. Resterebbe poi la questione minore (che se, come credo, si tratta di programma didattico, allora diventa irrilevante), che dopo diversi ritocchi alla lista, l'ordine numerico (inizialmente crescente) nella disposizione degli elementi si scombina continuamente. A questo si può ovviare senza ricorrere ad algoritmi di ordinamento, ma con un opportuno controllo in libera e ins_mezzo.
    Ultima modifica di filips; 06-09-2016 a 14:47
    Per fare un tavolo ci vuole un fiore.

  10. #10
    Quote Originariamente inviata da filips Visualizza il messaggio
    Perfetto, ora direi che è a posto. In effetti non avevo testato sulla testa ed è ovvio che col codice dato si abbia il crash. Resterebbe poi la questione minore (che se, come credo, si tratta di programma didattico, allora diventa irrilevante), che dopo diversi ritocchi alla lista, l'ordine numerico (inizialmente crescente) nella disposizione degli elementi si scombina continuamente.
    si l'avevo già pensato solo che non è richiesto nell'esercizio.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.