Compilare su più file sorgente

di il
9 risposte

Compilare su più file sorgente

Salve a tutti sto provando a compilare un programma c su più file sorgente, per non avere le varie funzioni nello stesso file contenente il main.
Per farlo ho creato un file .h dove ho inserito i prototipi di funzione, un file .c con lo stesso nome del file .h contenente le definizioni di funzione, e all'interno del file .c contenente il main ho incluso scrivendo #include ''nome.h' l'header file, ma quando vado a compilare mi da un casino di errori.
Cosa sbaglio?

9 Risposte

  • Re: Compilare su più file sorgente

    Non ti sembra che manchi qualcosa?
  • Re: Compilare su più file sorgente

    Cosa? Ho letto da delle dispense online come fare e ho fatto così, sul libro di testo non ho trovato nulla a riguardo
  • Re: Compilare su più file sorgente

    Manca il codice e l'errore, altrimenti che si risponde?
  • Re: Compilare su più file sorgente

    Devi scrivere il codice...
    Cmq in teoria hai bisogno di far capire al compilatore che hai bisogno di linkare i sorgenti...cosa che lui fa se sa di farlo
    Se usi una libreria di sistema #include <nomeLibreria.h>
    Se usi una tua libreria #include "percorso\nome\Tua\Libreria.h" o forse con i singoli apici ' non ricordo
    Riguarda il preprocessore, che esegue tutta una serie di traduzioni iniziali, come le define le include le costanti ecc ecc...
    prima che la compilazione venga completata.
    A compilazione completata si avrà un unico file exe.
    Questo è il binario ossia il codice che la macchina caricherà in memoria.
    E' l'unico che può capire.
    E bisogna pure scrivere codice assembly per quel tipo di CPU(questo è relativo al compilatore, programmatore di sistemi)
    Spero di non aver scritto minxxxxxe.
    Volevo capire se ho capito...
    Insomma non è proprio cosi semplice..
    Ma una lettura su cosa è il compilatore, va almeno data per capire i meccanismi
  • Re: Compilare su più file sorgente

    Sotto ho postato come ho creato i file, e in basso gli errori che mi restituisce relativi al file club.c. Ho provato a lasciare le definizioni delle strutture dati all'interno del file club.c e le ho rimosse dal file funz.h, ma a questo punto mi da 7 errori provenienti dal file funz.h :

    Epoca\funz.h|10|error: unknown type name 'SocioPtr'|

    Cosa sbaglio?


    Questo è il file contenente il main club.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "funz.h"
    
    
    
    
    
    //************** V A R I  T Y P E D E F **************
    
    typedef struct socio Socio;
    typedef Socio *SocioPtr;
    
    typedef struct vettura Vettura;
    typedef Vettura *VetturaPtr;
    
    //************** M A I N **************
    
    int main (void)
    {
    
    //Puntatori utili (puntatore di testa e puntatore che conterrà l'indirizzo di ritorno della funzione che cerca i soci)
    
    SocioPtr head = NULL;
    
    SocioPtr SocioTrovatoPtr = NULL;
    
    
    
    int scelta;  //Variabile utilizzata per l'accesso al menù
    menu();
    printf("\t\t\t\tFai una scelta [1-4]: ");
    scanf("%d", &scelta);
        while (scelta <= 4 && scelta >= 1)  //Quando scelta è diversa da 4 entra nello switch
        {
            switch (scelta)
            {
                case 1:
                        system("cls");
                        if (head == NULL)  //Se la lista è vuota entra nell'if, altrimenti riga 85
                        {
                            head = crea_socio();  //Crea un socio e restituisce a head l'indirizzo del nuovo socio
                            char conferma;  //Variabile utilizzata per confermare o meno l'inserimento di altri soci
                            printf("Vuoi aggiungere un altro socio al CLUB?: ");
                            fflush(stdin);
                            scanf("%c", &conferma);
                            system("cls");
                            while (conferma == 's')  //Fin tanto che viene premuto 's' entra nel while, appena finisci riga 83
                            {
                                if (head != NULL) //Se head non punta a NULL entra nell'if e inserisci ordinatamente i soci
                                {
                                    inserisci_ordina_socio(&head);  //Funzione che permette l'inserimento ordinato per Cognome e Nome
                                    printf("Vuoi aggiungere un altro socio al CLUB?: ");
                                    scanf("%c", &conferma);
                                    system("cls");
                                }
                                else  //Se head dovesse puntare a NULL significherebbe che l'allocazione non è andata a buon fine, quindi rientra nel while (riga 70) e riprova
                                {
                                    printf("Errore! Allocazione memoria non andata a buon fine!\n");
                                }
                            }
                        stampa_soci(head); //Terminato l'inserimento vengono stampati i soci mediante questa funzione
    
                        }
                        else  //Si arriva a questa riga (riga 85) se la lista è stata già riempita inizialmente e adesso si vogliono inserire altri soci dopo aver aggiunto vetture o fatto altro
                              //se non vi fosse questo else, ogni volta che si accede al case 1 i dati vengono eliminati e non aggiornati
                           {
                            inserisci_ordina_socio(&head);  //Inserisce ordinatamente i soci per Cognome e Nome
                            char conferma2;  //Variabile per la conferma o meno dell'inserimento di altri soci
                            printf("Vuoi aggiungere un altro socio al CLUB?: ");
                            fflush(stdin);
                            scanf("%c", &conferma2);
                            system("cls");
                            while (conferma2 == 's') //Fin tanto che la conferma è 's' entra nel while (Viene chiesta nuovamente conferma dentro l'if)
                            {
                                if (head != NULL) //Se il puntatore non è NULL entra nell'if
                                {
                                    inserisci_ordina_socio(&head); //Inserisce ordinatamente i soci per Cognome e Nome
                                    printf("Vuoi aggiungere un altro socio al CLUB?: ");
                                    scanf("%c", &conferma2);
                                    system("cls");
                                }
                                else
                                {
                                    printf("Errore! Allocazione memoria non andata a buon fine\n"); //Se il puntatore head è NULL la memoria non è stata allocata
                                }
                            }
                        stampa_soci(head); //Stampa i soci del club
    
                        }
                        break;   //Esce dal Case 1 e va alla riga 135 a chiedere nuovamente di fare una scelta
                    case 2:
                        system("cls");
                        if(head != NULL) //Se head non punta a NULL e quindi la lista è stata riempita entra nell'if, altrimenti vai alla riga 116
                        {
                            email(head); //Attraverso questa funzione viene inserito il modello di una vettura ed un periodo temporale
                        }                //e viene passato come argomento la testa della lista (essa restituisce le mail di tutti i clienti che posseggono
                                         //quella vettura ed è stata prodotta in quell'intervallo di tempo
                        else
                        {
                            printf("\nNessun socio registrato al CLUB AUTO D'EPOCA!\n");  //Se non entra nell'if significa che non vi sono utenti registrati al club
                        }
                        break;  //Esci e vai alla riga 136
                    case 3:
                        system("cls");
    
                        SocioTrovatoPtr = cerca_cf(head);//La funzione cerca_cf() permette di inserire il c.f. di un socio e restituisce il puntatore al cliente (se lo trova)
                        if (SocioTrovatoPtr != NULL)  //Se trova il cliente entra nell'if, altrimenti vai alla riga 127
                        {
                            vettura(SocioTrovatoPtr); //Se entra nell'if, permetti l'inserimento di una vettura per quel cliente
                        }
                        else
                        {
                            printf("\nNessun socio registrato al CLUB AUTO D'EPOCA!\n"); //Se non è entrato nell'if significa che la funzione cerca_cf() non ha trovato alcun socio
                        }
                        break;
                    case 4:
                        system("cls");
                        stampa_soci(head);
                        break;
            }
      menu();
      printf("\nFai una scelta [1-4]: ");
      fflush(stdin);
      scanf("%d", &scelta);
    
        }  //FINE WHILE DI SCELTA!!
    system("cls");
    printf("\n\t\t\t\t ------------------- P R O G R A M M A     T E R M I N A T O -------------------\n");
    system("pause");
    return 0;
    }
    
    
    
    
    
    

    Questo è il file funz.h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //************** S T R U T T U R E  D A T I **************
    
    struct vettura
    {
        char marca[20];
        char modello[20];
        int anno;
        struct vettura *proxVetturaPtr;
    };
    
    struct socio
    {
        char cognome[25];
        char nome[25];
        char cf[17];
        char mail[30];
        struct socio *ProxSocioPtr;
        struct vettura *proxVetturaPtr;
    };
    
    //************** V A R I  T Y P E D E F **************
    
    typedef struct socio Socio;
    typedef Socio *SocioPtr;
    
    typedef struct vettura Vettura;
    typedef Vettura *VetturaPtr;
    
    //************** P R O T O T I P I  D I  F U N Z I O N E **************
    
    void menu();
    SocioPtr crea_socio();
    void inserisci_ordina_socio(SocioPtr *testa);
    void stampa_soci(SocioPtr testa);
    void email(SocioPtr testa);
    void vettura(SocioPtr testa);
    SocioPtr cerca_cf(SocioPtr testa);
    
    
    
    
    E questo è il file funz.c

    void menu()
    {
    printf("\n\t\t\t\t================ C L U B   A U T O  D' E P O C A ====================\n");
    printf("\t\t\t\t|                -1. Inserisci un nuovo socio                         |\n");
    printf("\t\t\t\t|                -2. Cerca soci aventi la stessa vettura              |\n");
    printf("\t\t\t\t|                -3. Aggiungi vettura ad un socio                     |\n");
    printf("\t\t\t\t|                -4. Stampa riepilogo soci e auto                     |\n");
    printf("\t\t\t\t|                -5. ESCI DAL MENU' DEL CLUB                          |\n");
    printf("\t\t\t\t=======================================================================\n");
    };
    
    SocioPtr crea_socio()
    {
    SocioPtr nuovoPtr = malloc(sizeof(Socio));
    
        if (nuovoPtr != NULL)
            {
                printf("Inserisci NOME del nuovo socio: ");
                fflush(stdin);
                gets(nuovoPtr->nome);
                printf("Inserisci COGNOME del nuovo socio: ");
                fflush(stdin);
                gets(nuovoPtr->cognome);
                printf("Inserisci CODICE FISCALE del nuovo socio: ");
                fflush(stdin);
                gets(nuovoPtr->cf);
                printf("Inserisci E-MAIL del nuovo socio: ");
                fflush(stdin);
                gets(nuovoPtr->mail);
                fflush(stdin);
                nuovoPtr->ProxSocioPtr = NULL;
                //nuovoPtr->proxVetturaPtr = NULL;
            }
        else
            {
                printf("Errore! Allocazione della memoria non andata a buon fine\n");
            }
    return nuovoPtr;
    };
    
    void inserisci_ordina_socio(SocioPtr *testa)
    {
    SocioPtr nuovoPtr = malloc(sizeof(Socio));
    
    
        if (nuovoPtr != NULL)
        {
            SocioPtr previusPtr = NULL;
            SocioPtr currentPtr = *testa;
    
            printf("Inserisci NOME del nuovo socio: ");
            fflush(stdin);
            gets(nuovoPtr->nome);
            fflush(stdin);
            printf("Inserisci COGNOME del nuovo socio: ");
            fflush(stdin);
            gets(nuovoPtr->cognome);
            printf("Inserisci CODICE FISCALE del nuovo socio: ");
            fflush(stdin);
            gets(nuovoPtr->cf);
            printf("Inserisci E-MAIL del nuovo socio: ");
            fflush(stdin);
            gets(nuovoPtr->mail);
            nuovoPtr->ProxSocioPtr = NULL;
           // nuovoPtr->proxVetturaPtr = NULL;
    
            //Ordina per cognome e nome
            if (strcmp(nuovoPtr->cognome, currentPtr->cognome) <= 0)
            {
                //se il cognome che si vuole inserire è minore o uguale rispetto al primo cognome in lista, quello nuovo ma messo in testa
                if (strcmp(nuovoPtr->cognome, currentPtr->cognome) < 0)
                {
                    nuovoPtr->ProxSocioPtr = (*testa);
                    (*testa) = nuovoPtr;
                }
                else  //significa che il cognome che si vuole inserire è uguale al primo della lista, allora ordina per nome
                {
                    if (strcmp(nuovoPtr->nome, currentPtr->nome) <= 0)
                    {
                       //se il nome che si vuole inserire è minore o uguale rispetto al primo nome, quello nuovo ma messo in testa
                       nuovoPtr->ProxSocioPtr = (*testa);
                       (*testa) = nuovoPtr;
                    }
                    else if (strcmp(nuovoPtr->nome, currentPtr->nome) > 0)
                    {
                        //se invece il nome che vogliamo inserire è maggiore al successivo, allora quello nuovo va dopo, ma bisogna tenere in conto anche di quello dopo
                        while (currentPtr != NULL && strcmp(nuovoPtr->nome, currentPtr->nome) > 0) //finche è maggiore di 0, dobbiamo andare avanti
                        {
                            previusPtr = currentPtr;
                            currentPtr = currentPtr->ProxSocioPtr;
                        }
                            if (currentPtr == NULL)
                            {
                                previusPtr->ProxSocioPtr = nuovoPtr;
                            }
                            else
                            {
                            //significa che strcmp ha cambiato segno
                            //se è diventato minore
                                if (strcmp(nuovoPtr->nome, currentPtr->nome) <= 0)
                                {
                                    nuovoPtr->ProxSocioPtr = currentPtr;
                                    previusPtr->ProxSocioPtr = nuovoPtr;
                                }
                            }
                    }
                }
            }
            else if (strcmp(nuovoPtr->cognome, currentPtr->cognome) > 0)
            {
                //se invece il cognome che vogliamo inserire è maggiore al successivo, allora quello nuovo va dopo, ma bisogna tenere in conto anche di quello dopo
                while (currentPtr != NULL && strcmp(nuovoPtr->cognome, currentPtr->cognome) > 0) //finche è maggiore di 0, dobbiamo andare avanti
                {
                    previusPtr = currentPtr;
                    currentPtr = currentPtr->ProxSocioPtr;
                }
                    if (currentPtr == NULL)
                    {
                        previusPtr->ProxSocioPtr = nuovoPtr;
                    }
                    else
                    {
                    //significa che strcmp ha cambiato segno
                        //se è diventato minore
                        if (strcmp(nuovoPtr->cognome, currentPtr->cognome) <= 0)
                            {
                                //va inserito prima di questo
                                nuovoPtr->ProxSocioPtr = currentPtr;
                                previusPtr->ProxSocioPtr = nuovoPtr;
                            }
                            else //se è diventato uguale, ordina per nome
                            {
                                if (strcmp(nuovoPtr->nome, currentPtr->nome) <= 0)
                                {
                                    //se il nome che si vuole inserire è minore o uguale rispetto al primo nome, quello nuovo ma messo in testa
                                    nuovoPtr->ProxSocioPtr = (*testa);
                                    (*testa) = nuovoPtr;
                                }
                                else if (strcmp(nuovoPtr->nome, currentPtr->nome) > 0)
                                {
                                    //se invece il nome che vogliamo inserire è maggiore al successivo, allora quello nuovo va dopo, ma bisogna tenere in conto anche di quello dopo
                                    while (currentPtr != NULL && strcmp(nuovoPtr->nome, currentPtr->nome) > 0) //finche è maggiore di 0, dobbiamo andare avanti
                                    {
                                        previusPtr = currentPtr;
                                        currentPtr = currentPtr->ProxSocioPtr;
                                    }
                                        if (currentPtr == NULL)
                                        {
                                            previusPtr->ProxSocioPtr = nuovoPtr;
                                        }
                                        else
                                        {
                                        //significa che strcmp ha cambiato segno
                                            //se è diventato minore
                                            if (strcmp(nuovoPtr->nome, currentPtr->nome) <= 0)
                                            {
                                                //va inserito prima di questo
                                                nuovoPtr->ProxSocioPtr = currentPtr;
                                                previusPtr->ProxSocioPtr = nuovoPtr;
                                            }
                                        }
                                }
                            }
                    }
            }
        }
    else
     {
        printf("Errore! Allocazione della memoria non andata a buon fine\n");
     }
    
    };
    
    void stampa_soci(SocioPtr testa)
    {
    int x = 1;
    int y = 1;
    
    VetturaPtr aux = NULL;
    
      if(testa != NULL)
      {
        while (testa != NULL)
        {
            printf("\n--------------------------------------------------\n");
            printf("Socio (%d) : '%s %s'\n", x, testa->nome, testa->cognome);
            aux = testa->proxVetturaPtr;
            if(aux == NULL)
            {
                printf("Il socio non possiede auto\n");
            }
            while (aux != NULL)
            {
                printf("Auto (%d) : '%s %s'\n", y, aux->marca, aux->modello);
                aux = aux->proxVetturaPtr;
                y++;
            }
            printf("\n--------------------------------------------------\n");
        testa = testa->ProxSocioPtr;
        x++;
        }
      }
      else
      {
         printf("\nNessun socio registrato al CLUB AUTO D'EPOCA!\n");
      }
    
    };
    
    void email(SocioPtr testa)
    {
      VetturaPtr ricercaPtr;
      ricercaPtr = testa->proxVetturaPtr;
    
      char modello[20];
      int anno0, anno1;
    
      printf("Inserisci il MODELLO (solo il MODELLO) della vettura per visualizzare le E-MAIL degli utenti che la posseggono: ");
      fflush(stdin);
      gets(modello);
      printf("Inserisci i due anni di produzione della vettura separati da '-' : ");
      fflush(stdin);
      scanf("%d-%d", &anno0, &anno1);
    
      if(testa != NULL)
      {
        printf("\nLe E-MAIL dei soci che posseggono la vettura sono:\n");
          while (testa != NULL) //quando head non è null scansiona la sottolista
          {
                {
                while (ricercaPtr != NULL)
                {
                    if ( strcmp(modello, ricercaPtr->modello) == 0 && ( (ricercaPtr->anno >= anno0) && (ricercaPtr->anno <= anno1) ))
                    {
                        printf("%s\n", testa->mail);
                    }
                    ricercaPtr = ricercaPtr->proxVetturaPtr;
                }
            }
          testa = testa->ProxSocioPtr;
                if (testa != NULL)
                {
                    ricercaPtr = testa->proxVetturaPtr;
                }
        }
      }
      else
      {
        printf("Impossibile controllare le auto possedute! Nessun socio registrato al Club\n");
      }
    };
    
    void vettura(SocioPtr SocioTrovatoPtr) //SocioTrovatoPtr è il puntatore al socio di cui vogliamo inserire la vettura
    {
       VetturaPtr nuovaVettPtr = malloc(sizeof(Vettura));
    
       if (SocioTrovatoPtr->proxVetturaPtr == NULL) //Se il socio non ha ancora vetture
       {
            printf("Inserisci MARCA vettura: ");
            fflush(stdin);
            gets(nuovaVettPtr->marca);
            printf("Inserisci MODELLO vettura: ");
            fflush(stdin);
            gets(nuovaVettPtr->modello);
            printf("Inserisci ANNO di produzione della vettura: ");
            fflush(stdin);
            scanf("%d", &(nuovaVettPtr->anno));
    
            SocioTrovatoPtr->proxVetturaPtr = nuovaVettPtr;
            nuovaVettPtr->proxVetturaPtr = NULL;
            printf("Vettura associata! INVIO per continuare!");
            system("pause");
        }
        else //Inserisci in testa
        {
            VetturaPtr nuovoVettPtr1 = malloc(sizeof(Vettura));
            printf("Inserisci MARCA vettura: ");
            fflush(stdin);
            gets(nuovoVettPtr1->marca);
            printf("Inserisci MODELLO vettura: ");
            fflush(stdin);
            gets(nuovoVettPtr1->modello);
            printf("Inserisci ANNO di produzione della vettura: ");
            fflush(stdin);
            scanf("%d", &(nuovoVettPtr1->anno));
            nuovoVettPtr1->proxVetturaPtr = SocioTrovatoPtr->proxVetturaPtr;
            SocioTrovatoPtr->proxVetturaPtr = nuovoVettPtr1;
            printf("Vettura associata! INVIO per continuare!");
            system("pause");
        }
    };
    
    SocioPtr cerca_cf(SocioPtr testa)
    {
     if (testa != NULL)
     {
        char codfi[17];
        printf("Inserisci il CODICE FISCALE del socio a cui vuoi aggiungere un veicolo: ");
        fflush(stdin);
        scanf("%s", codfi);
    
            while(testa != NULL && strcmp(codfi, testa->cf) != 0)
            {
                testa= testa->ProxSocioPtr;
            }
            return testa;
     }
     else
     {
        return testa;
     }
    };
    
    Gli errori restituiti sono i seguenti e sono relativi al file club.c

    ||=== Build file: "no target" in "no project" (compiler: unknown) ===|
    || undefined reference to `menu'|
    || undefined reference to `crea_socio'|
    || undefined reference to `inserisci_ordina_socio'|
    || undefined reference to `stampa_soci'|
    || undefined reference to `inserisci_ordina_socio'|
    || undefined reference to `inserisci_ordina_socio'|
    || undefined reference to `stampa_soci'|
    || undefined reference to `email'|
    || undefined reference to `cerca_cf'|
    || undefined reference to `vettura'|
    || undefined reference to `stampa_soci'|
    || undefined reference to `menu'|
    ||error: ld returned 1 exit status|
    ||=== Build failed: 13 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
  • Re: Compilare su più file sorgente

    Ma come hai compilato?
  • Re: Compilare su più file sorgente

    Ho compilato il solo file del main e gli altri file li ho salvati nella stessa cartella
  • Re: Compilare su più file sorgente

    No.

    Devi compilare indicando al compilatore tutti i file .c
  • Re: Compilare su più file sorgente

    Perfetto funziona, grazie mille !!
Devi accedere o registrarti per scrivere nel forum
9 risposte