Strutture innestate

di il
13 risposte

Strutture innestate

Salve a tutti sto provando a "scrivere" attraverso una funzione su delle strutture innestate, e riscontro qualche problema durante l'inserimento.
L'errore che mi viene restituito è :

struct.c|33|error: request for member 'a' in something not a structure or union|
struct.c|34|error: request for member 'secondaria' in something not a structure or union|

Il codice che ho scritto serve solo per far capire il tipo di problema, il programma che stavo cercando di scrivere era un tema d'esame sulla gestione di un conto corrente bancario e il problema riguardava sempre l'inserimento di clienti su una struttura di struttura.
Quello che non capisco è a cosa sia dovuto questo errore, e come fare per risolverlo. C'è qualcosa che mi sfugge


il codice è :

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

struct principale
{
    int a;
    struct secondaria
    {
        int b;
    };
};

void inserisci(struct principale **priPtr);




int main (void)
{

struct principale *principalePtr = NULL;

inserisci(&principalePtr);

system("pause");
return 0;
}

void inserisci(struct principale **priPtr)
{

priPtr = malloc(sizeof(struct principale));
priPtr->a = 5;
priPtr->secondaria.b = 8;

};

13 Risposte

  • Re: Strutture innestate

    Secondaria è solo una dichiarazione non una variabile.
    
    struct principale
    {
        int a;
        struct secondaria
        {
            int b;
        } second;
    };
    ...
    priPtr->second.b = 8;
    
  • Re: Strutture innestate

    E non vale la stessa cosa anche per principale?
    Comunque ho modificato il codice e mi da lo stesso errore
  • Re: Strutture innestate

    No, perché alla funzione passi un doppio puntatore. Tra l'altro l'allocazione è sbagliata, dev'essere:
    
    *priPtr = malloc(sizeof(struct principale));
    (*priPtr)->a = ...etc
    
    Come hai fatto tu il comportamento è indefinito (può andare bene, può andare male...)
  • Re: Strutture innestate

    Perfetto grazie mille, adesso non mi da più errori
  • Re: Strutture innestate

    Non ho però ancora ben capito perchè non dovrei fare lo stesso con la struttura principale.
  • Re: Strutture innestate

    Perché nel main ne dichiari il puntatore
    
    struct principale *principalePtr = NULL;
    
    non stai scrivendo
    
    struct principale * = NULL;
    
    che non ha senso.
    Così come non ha senso:
    
    struct principale.int = 5;
    
  • Re: Strutture innestate

    Pensavo che dichiarando
    struct principale *principalePtr = NULL;


    fosse sottointesa anche la dichiarazione della struttura secondaria innestata.

    Quindi per esempio se mi creassi una struttura principale che chiamerò Cliente e all'interno di essa creo delle sottostrutture
    che contengono altri parametri del Cliente, per poter accedere a queste sottostruttere, devo dichiarare una variabile del tipo della sottostruttura
    e posso sempre accedere attraverso il puntatore alla struttura Cliente.

    Giusto?
  • Re: Strutture innestate

    Ogni struttura a il suo puntatore di accesso.
  • Re: Strutture innestate

    Per il programma di cui parlavo prima io ho creato una struttura di questo genere per accedere a giorno mese e anno partendo dalla struttura cliente dovrei creare un puntatore a struct data? Ma facendo così non è come se riempissi giorno mese e anno di una struttura a parte?
    Io per ogni cliente devo inserire il giorno il mese e l'anno dell'operazione. Quindi suppongo che per un determinato cliente l'accesso alla struttura dovrebbe partire dalla struttura cliente in modo tale da identificare il cliente corretto
    
    struct lista_movimenti
    {
        float importo_movimento;
        int numerocc;
        struct data
        {
            int giorno;
            int mese;
            int anno;
        };
        struct lista_movimenti *prossimo_movimentoPtr;
    };
    
    
    struct cliente
    {
        char cognome[20];
        char nome[20];
        char cf[16];
        char email[20];
        int numero_conto;
        char username[10];
        char password[10];
    
        struct cliente *prossimo_clientePtr; //Puntatore alla prossima struttura cliente
    
        struct conto_cliente                 //Struttura contenente un saldo e un puntatore alla struttura dei movimenti
        {
            float saldo;
            struct lista_movimenti *movimenti;
        };
    
    };
    
    
  • Re: Strutture innestate

    fosse sottointesa anche la dichiarazione della struttura secondaria innestata.
    La struttura di per se è solo una definizione di come dev'essere fatta una determinata variabile.
    Se non hai una variabile di quel tipo, il compilatore non ne crea una al volo.
    dovrei creare un puntatore a struct data?
    Non serve. Esempio di prima:
    
    struct principale
    {
        int a;
        struct secondaria
        {
            int b;
    
            struct terziaria {
               int c;
            } third;
    
        } second;
    };
    
    ...
    	(*priPtr)->second.third.c = 20;
    
  • Re: Strutture innestate

    Grazie mille per la tua disponibilità!
  • Re: Strutture innestate

    Ciao ho nuovamente un problema simile ma non capisco cosa sbaglio, spero potrai darmi una mano:
    Il codice è il seguente, in alcuni pezzi del main ci sono righe non sintatticamente corrette come nel "case 1:" ma le ho scritte così per farmi una sequenza delle cose da fare.
    Il problema che ho in questo caso è che non riesco attraverso la funzione crea_lista_cliente ad inserire giorno mese e anno , la riga di codice dove mi da segmentation fault è questa:
       scanf("%d/%d/%d", &(nuovo_cliente->conto_cliente0.movimenti->data0.giorno), &(nuovo_cliente->conto_cliente0.movimenti->data0.mese), &(nuovo_cliente->conto_cliente0.movimenti->data0.anno) );

    Grazie in anticipo

    
    
    //07-03-2017
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PULISCI fflush(stdin)
    
    /** S T R U T T U R E   D A T I **/
    
    struct lista_movimenti
    {
        float importo_movimento;
        int numerocc;
        struct data
        {
            int giorno;
            int mese;
            int anno;
        }data0;
        struct lista_movimenti *prossimo_movimentoPtr;
    };
    
    
    struct cliente
    {
        char cognome[20];
        char nome[20];
        char cf[16];
        char email[20];
        int numero_conto;
        char username[10];
        char password[10];
    
        struct cliente *prossimo_clientePtr; //Puntatore alla prossima struttura cliente
    
        struct conto_cliente                 //Struttura contenente un saldo e un puntatore alla struttura dei movimenti
        {
            float saldo;
            struct lista_movimenti *movimenti;
        }conto_cliente0;
    
    };
    
    /** V A R I   T Y P E D E F **/
    
    typedef struct cliente Cliente;
    typedef Cliente *ClientePtr;
    
    
    
    typedef struct lista_movimenti ListaMovimenti;
    typedef ListaMovimenti *ListaMovimentiPtr;
    
    /** P R O T O T I P I   D I   F U N Z I O N E **/
    
    void menu();
    int login_impiegato(char user[], char password[]);
    int login_impiegato1();
    ClientePtr crea_lista_cliente();
    void inserisci_nuovo_cliente(ClientePtr *testa);
    
    
    /** M A I N **/
    
    int main (void)
    {
    int scelta, scelta2;
    
    char username_imp[10];
    char password_imp[10];
    
    
    ClientePtr head_clientePtr = NULL;  //Crea un nuovo puntatore alla struttura cliente che inizialmente punta a NULL
    do{
        if (head_clientePtr == NULL)
        {
        scelta = 2;
        }
        else
        {
        menu();
        printf("Fai una scelta: ");
        fflush(stdin);
        scanf("%d", &scelta);
        }
            switch (scelta)
            {
                case 1:
                    {/*
                        switch (scelta1)
                        {
                        case 1: login_cliente()
                        case 2: saldo()
                        case 3: bonifico()
                        case 4: listamovpers()
                        }*/
                    }
                case 2:
                    {
                        int esito_login;
                        char scelta3;
                        if (head_clientePtr == NULL)
                        {
    
                            esito_login = login_impiegato1();
                            if (esito_login == 1)   //Se è vera sei loggato
                            {
                                printf("Inserimento dei NUOVI CLIENTI\n");
                                head_clientePtr = crea_lista_cliente();
                                do
                                {
                                printf("Vuoi inserire altri clienti? S o N: ");
                                PULISCI;
                                scanf("%c", &scelta3);
                                if (scelta3 == 's' || scelta3 == 'S')
                                    {
                                    printf("Inserimento di un nuovo cliente:\n");
                                    inserisci_nuovo_cliente(&head_clientePtr);
                                    }
                                }
                                while (scelta3 == 's' || scelta3 == 'S');
                            }
                        }
                        else
                        {
                            fflush(stdin);
                            esito_login = login_impiegato1();
                            if (esito_login == 1)
                                //sotto_menu();
                                printf("Fai una scelta: ");
                                fflush(stdin);
                                scanf("%d", &scelta2);
                                switch (scelta2)
                                {
    
                            /*
                                    case 1: saldo()
                                    case 2: listamov1()
                                    case 3: listamovAll()
                                    case 4: salva()*/
                                }
                        }
    
                    }
                    break;
    
    
            }
    }
    while (scelta != 3);
    
    
    
    
    system("pause");
    return 0;
    }
    
    void menu()
    {
        printf("\t\t******************* Benvenuto nella BANCA, che operazione intendi eseguire? ********************\n");
        printf("\t\t*                    -1)  Login come CLIENTE della banca                                       *\n");
        printf("\t\t*                    -2)  Login come IMPIEGATO della banca                                     *\n");
        printf("\t\t************************************************************************************************\n");
    };
    
    int login_impiegato(char user[], char password[])
    {
        char us[] = "user";
        char pw[] = "user";
        int esito_user;
        int esito_password;
        esito_user = strcmp(user, us);
        esito_password = strcmp(password, pw);
        if (esito_user == 0 && esito_password == 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    int login_impiegato1()
    {
    int stato_login;
    char username_imp[10];
    char password_imp[10];
    
    int n = 10;
    puts("Inserire Username impiegato: ");
    gets(username_imp);
    puts("Inserire Password impiegato: ");
    gets(password_imp);
    stato_login = login_impiegato(username_imp, password_imp);
        if (stato_login == 1)
        {
            printf("Credenziali accettate\n");
            return 1;
        }
        else
        {
            printf("Credenziali errate\n");
            return 0;
        }
    };
    
    ClientePtr crea_lista_cliente()
    {
        ClientePtr nuovo_cliente = malloc(sizeof(Cliente));
    
    
        printf("Inserisci il Nome del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->nome);
        printf("Inserisci il Cognome del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->cognome);
        printf("Inserisci il C.F del nuovo cliente: ");
        PULISCI;
        scanf("%16s", nuovo_cliente->cf);
        int trovato;
        do {
        printf("Inserisci Indirizzo E-Mail del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->email);
        char *mail = nuovo_cliente->email;
        int i;
            for (i = 0; i<20; i++)
            {
                if (mail[i] == '@')
                    {
                    trovato = 1;
                    break;
                    }
                else
                    trovato = 0;
            }
        }
        while(!trovato);
    
        printf("Inserisci Numero Conto del nuovo cliente: ");
        PULISCI;
        scanf("%10d", &(nuovo_cliente->numero_conto));
    
        printf("Inserisci Username del nuovo cliente: ");
        PULISCI;
        scanf("%10s", nuovo_cliente->username);
        printf("Inserici Password del nuovo cliente: ");
        PULISCI;
        scanf("%10s", nuovo_cliente->password);
        PULISCI;
        printf("Inserisci Saldo del nuovo cliente: ");
        scanf("%f", &(nuovo_cliente->conto_cliente0.saldo));
        PULISCI;
        printf("Inserisci Data operazione in formato (gg/mm/aaaa): ");
        scanf("%d/%d/%d", &(nuovo_cliente->conto_cliente0.movimenti->data0.giorno), &(nuovo_cliente->conto_cliente0.movimenti->data0.mese), &(nuovo_cliente->conto_cliente0.movimenti->data0.anno) );
    
        nuovo_cliente->prossimo_clientePtr = NULL;
        return nuovo_cliente;
    };
    
    
    void inserisci_nuovo_cliente(ClientePtr *testa)
    {
        ClientePtr nuovo_cliente = malloc(sizeof(Cliente));
    
        printf("Inserisci il Nome del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->nome);
        printf("Inserisci il Cognome del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->cognome);
        printf("Inserisci il C.F del nuovo cliente: ");
        PULISCI;
        scanf("%16s", nuovo_cliente->cf);
        printf("Inserisci Indirizzo E-Mail del nuovo cliente: ");
        PULISCI;
        scanf("%20s", nuovo_cliente->email);
        printf("Inserisci Numero Conto del nuovo cliente: ");
        PULISCI;
        scanf("%10d", nuovo_cliente->numero_conto);
        printf("Inserisci Username del nuovo cliente: ");
        PULISCI;
        scanf("%10s", nuovo_cliente->username);
        printf("Inserici Password del nuovo cliente: ");
        PULISCI;
        scanf("%10s", nuovo_cliente->password);
    
        nuovo_cliente->prossimo_clientePtr = *testa;
        *testa = nuovo_cliente;
    
    };
    
    
  • Re: Strutture innestate

    Non hai creato la lista dei movimenti.
Devi accedere o registrarti per scrivere nel forum
13 risposte