Problema liste e strutture(C)

di il
1 risposte

Problema liste e strutture(C)

Ciao a tutti! Avrei bisogno del vostro aiuto.
Sono alle prese con un compito di esame di Fondamenti 2 in linguaggio C, il testo è il seguente:

Si scriva un programma C per la gestione dell’archivio dei soci di un club di macchine d'epoca. In particolare, i dati da mantenere per ciascun associato sono i seguenti:
– Cognome (stringa di massimo 20 caratteri, può contenere spazi al suo interno)
– Nome (stringa di massimo 20 caratteri, può contenere spazi al suo interno)
– Codice fiscale
– Indirizzo e-mail
– Vetture possedute

Ogni vettura è caratterizzata da:
• Marca
• modello
• anno di produzione
Dopo aver definito le appropriate strutture dati idonee a mantenere le informazioni dette, definire le seguenti funzioni:
Socio: funzione che ha come parametri i dati di una persona e li inserisce nella struttura dati atta a memorizzarli: essa deve leggere le informazioni da standard input ed inserirle in modo ordinato rispetto al cognome e nome;
Email: funzione che, accettando in ingresso un modello di vettura ed un periodo temporale definito da due anni, visualizzi su standard output gli indirizzi e-mail di tutti i soci che possiedono una vettura del tipo definito e prodotta nel periodo dato in input;
Vettura:funzione che accettando in ingresso il codice fiscale di un socio, permette di aggiungere una vettura a lui associata;
main: all’interno del main predisporre un opportuno menu che permetta di scegliere e far eseguire le diverse funzioni implementate.

La mia difficoltà è nell'associare ai soci le vetture da loro possedute tramite liste, strutture e puntatori vari, cioè memorizzare le vetture nella struttura vetture e poi associarle al socio della lista soci che le possiede. In poche parole creare strutture di strutture con le liste. Ho trovato pochi esercizi svolti a riguardo e sto trovando difficoltà. Spero possiate aiutarmi.
Posto quello che ho fatto fino adesso così si capisce meglio dove sta il mio problema:

#include <stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct Vetture{
    char marca[20];
    char modello[20];
    int anno;
    struct Vetture *next;
}vetture;

typedef struct Soci{
    
    char nome[20];
    char cognome[20];
    char cod[16];
    char email[30];
    vetture *vettposs;
    struct Soci *next;
}soci;



void aggiungiSocio(soci **head, char nome[20], char cognome[20], char cod[16], char email[30]){
    
    soci *r=*head, *q=*head;
    soci *p=(soci*)malloc(sizeof(soci));
    
    strcpy(p->nome, nome);
    strcpy(p->cognome, cognome);
    strcpy(p->cod, cod);
    strcpy(p->email, email);
    
    p->vettposs=NULL;
    
    while ((q!=NULL) && (strcmp(q->cognome, p->cognome)<0)){
        r=q;
        q=q->next;
    }
    
    if(q==*head){
    *head=p;
    }
    else
        r->next=p;
    p->next=q;
    
    
    
}


vetture *aggiungiVettura(vetture *headVetture, char marca[20], char modello[20], int anno){
    
    vetture *p;
    p=(vetture*)malloc(sizeof(vetture));
    
    
    
    strcpy(p->marca, marca);
    strcpy(p->modello, modello);
    p->anno=anno;
    if (headVetture==NULL) {
        p->next=NULL;
    }
    else
    {
        p->next=headVetture;
    }
    
    return p;
    
}


void visualizza(soci *head){
    
    soci *elem;
    elem=head;
    while (elem!=NULL) {
        printf("Nome %s\n", elem->nome);
        printf("Cognome %s\n", elem->cognome);
        printf("Codice fiscale %s\n", elem->cod);
        printf("Email %s\n\n", elem->email);
        
        elem=elem->next;
    }
    

    
    
}

int main(int argc, const char * argv[]) {
    
    soci *head=NULL, *p;
    vetture *headVetture=NULL;
    int scelta, anno, trovato=0;
    
    char nome[20], cognome[20], cod[16], email[30], marca[20], modello[20];
    
    
    do{
        printf("1-INSERISCI SOCIO\n");
        printf("2-INSERISCI VETTURA E ANNO E STAMPA EMAIL SOCI\n");
        printf("3-INSERISCI CODICE FISCALE E AGGIUNGI VETTURA AL SOCIO\n");
        printf("4-VISUALIZZA SOCI\n");
        printf("0-ESCI\n");
    scanf("%d", &scelta);
    fflush(stdin);
    switch (scelta) {
        case 1:
            printf("Inserisci nome:\n");
            gets(nome);
            printf("Inserisci cognome:\n");
            gets(cognome);
            printf("Inserisci codice fiscale:\n");
            scanf("%s", cod);
            printf("Inserisci email:\n");
            scanf("%s", email);
            aggiungiSocio(&head, nome, cognome, cod, email);
            break;
        case 2:
            
            break;
            
        case 3:
            printf("Inserisci codice fiscale del cliente: ");
            scanf("%s", cod);
            p=head;
            while (p!=NULL) {
            if (strcmp(p->cod,cod)==0) {
                trovato=1;
                break;
            }
            p=p->next;
            }
            if (trovato==1) {
                printf("Aggiungi vettura al cliente %s %s\n\n", p->nome, p->cognome);
                printf("Marca: ");
                scanf("%s", marca);
                printf("Modello:");
                scanf("%s", modello);
                printf("Anno:");
                scanf("%d", &anno);
                p->vettposs=aggiungiVettura(p->vettposs, marca, modello, anno);/*Il mio problema è qui. È giusto passare la funzione in questo modo alla lista soci per far memorizzare la vettura o più vetture possedute da un socio?*/
            }
            else{
                printf("Codice fiscale non trovato\n\n");
            }
            break;
        case 4:
             visualizza(head);
            break;
        default:printf("Non hai inserito una scelta valida\n\n");
            break;
    }
    }while (scelta!=0);

    return 0;
}

1 Risposte

  • Re: Problema liste e strutture(C)

    Adesso non ho il tempo di esaminare in dettaglio il tuo codice,
    se riesco lo faro' piu' avanti; ti fornisco una traccia
    su come risolverei il problema al tuo posto (e' un metodo alternativo).

    Fra soci e auto esiste una relazione molti a molti, perche'
    lo stesso socio puo' avere piu' auto e la stessa auto
    (cioe' con stessi marca, modello e anno prod.) puo' essere
    posseduta da piu' soci.

    Per gestire questo tipo di relazione, si puo' creare
    una terza struttura (in aggiunta a soci e auto)
    contenente i riferimenti incrociati, cioe' una coppia
    di puntatori che identificano ogni coppia esistente
    socio-auto.

    Esempio: ci sono tre soci Tizio, Caio e Sempronio
    e 5 modelli di auto, A, B, C, D, E.

    Si presenta Tizio, che dice di possedere le auto B, D, E;
    si inserisce Tizio nella lista dei soci, poi nella lista auto
    si mettono B, D, E; nella lista dei riferimenti incrociati
    si inseriscono tre strutture, con le coppie punta Tizio-punta B,
    punta Tizio-punta D, punta Tizio-punta E.

    Si presenta Caio, che possiede le auto C, D;
    si mette Caio nella lista dei soci e C in quella delle auto
    (D no, perche' c'e' gia'); nella lista dei riferimenti incrociati
    si memorizzano le coppie p.Caio-p.C, p.Caio-p.D.

    Infine arriva Sempronio, che possiede le auto A, B, E;
    si mette Sempronio nella lista dei soci e A in quella delle auto
    (B, E ci sono gia'); nella lista dei riferimenti incrociati
    si inseriscono le coppie p.Sempronio-p.A, p.Sempronio-p.B,
    p.Sempronio-p.E.

    Alla fine ti ritrovi con le seguenti tre liste:

    soci (in ordine alf.): Caio, Sempronio, Tizio;

    auto (in ordine di inserimento): B, D, E, C, A;

    lista rif. incr. (in ordine di inserimento):
    p.Tizio-p.B, p.Tizio-p.D, p.Tizio-p.E,
    p.Caio-p.C, p.Caio-p.D,
    p.Sempronio-p.A, p.Sempronio-p.B, p.Sempronio-p.E.

    Il metodo puo' funzionare anche inserendo prima tutti i soci,
    poi - con la funzione Vettura - le auto di ognuno.

    La funzione Email dovrebbe fare la scansione di tutta la lista
    dei rif. incr. e ogni volta che trova un puntatore all'auto cercata
    dovrebbe visualizzare (tramite puntatore) il socio corrispondente,
    col suo indirizzo e-mail.

    La funzione Vettura dovrebbe fare la scansione della lista dei soci,
    fermandosi su quello col CF richiesto, consentire di inserire
    nella lista delle auto una nuova auto (se non c'e' ancora)
    e inserire nella lista dei rif. incr. la coppia p.Socio-p.Auto.

    Si puo' anche prevedere il caso particolare di un socio
    che abbia piu' esemplari della stessa auto; in questo caso,
    nella coppia p.Socio-p.Auto si dovrebbe mettere un ulteriore campo
    che contenga il numero di auto possedute (di quel tipo).

    Lascio ai piu' esperti la valutazione della maggiore o minore
    efficienza di questa soluzione. La cosa sicura e' che in questo modo
    ogni auto viene inserita in lista una sola volta; invece,
    con la lista dei soci (ogni nodo della quale punta a una lista
    di auto) puo' capitare che la stessa auto compaia piu' volte
    in liste diverse; si puo' creare una ridondanza.

    Col mio metodo la ricerca dei soci (e dei relativi e-mail)
    che hanno una data auto implica la percorrenza di una sola lista,
    quella dei rif. incr.; con la lista dei soci, con nodi che puntano
    a liste di auto, bisogna percorrere la lista principale e,
    per ogni nodo, la lista delle auto. Col mio metodo, pero',
    e' un po' piu' complicato l'inserimento dei dati, dovendo
    gestire anche la memorizzazione nella lista dei rif. incr.
    (che occupa anche memoria).

    Vedi tu.
    
    typedef struct rif_incr
     {
      soci *p_socio;
      vettura *p_vettura;
      rif_incr *next;
     } rif_incr;
    
Devi accedere o registrarti per scrivere nel forum
1 risposte