Creare una libreria con devc - Prime armi

di il
31 risposte

Creare una libreria con devc - Prime armi

Salve a tutti, sono completamente alle prime armi quindi mi rendo conto che gli errori commessi possono essere veramente elementari, premesso ciò, la mia situazione è la seguente..
Devo creare una libreria in c, sto utilizzando devc..
Ho creato il progetto, e iniziato a scrivere la libreria.. inizialmente ho scritto in essa una sola funzione.. Ho creato un programmino che utilizzasse la funzione della mia libreria con un apposito #include "libreria.h" prima del main, e tutto funzionava. Quando ho aggiunto alla libreria una struttura dati, e un'altra funzione, non mi funziona più. In pratica il primo programmino che utilizza una sola funzione della mia libreria va in palla riportandomi errori sulla funzione non utilizzata.

Questa è la libreria:
//esercizio1.h

#include <string.h>

struct listapuntata {
       char *str;
       struct listapuntata *next;}; 
       
char *leggi (char *str) {
      
      scanf ("%s",str);
      return (str);
      }
      
listapuntata *inserimento(listapuntata *lista, listapuntata *prec, char *str)
{
     
      struct listapuntata *nodo, *nuovo;
      nodo=(struct listapuntata *) malloc(sizeof(struct listapuntata));
      nuovo= (struct listapuntata *) malloc(sizeof(struct listapuntata));
      nodo=lista;
      nuovo->str= str;
      
      if (lista != NULL)    
         {
            if ((strlen(str)) > (strlen(nodo->str)))
               {
                                  nodo=inserimento(nodo->next,nodo,str);
                                  }
            else {
                                  nuovo->next=nodo;
                                  prec->next=nuovo;
                    }
            }
      else
          {nuovo->next=NULL;}
                    
     
      system("PAUSE");
      
      return lista;
      }
Questo è il main:
#include <stdio.h>
#include <stdlib.h>
#include "esercizio1.h"

       
main()
{
      char *stringa;
      stringa=calloc(100, sizeof(char));
      printf ("Digita stringa da leggere: ");
      leggi(stringa);
      printf("\nLa stringa digitata è : %s\n", stringa);
      
      system("PAUSE");
      
      }
In pratica.. Se eseguo il main eliminando dalla libreria la struttura dati e la funzione inserimento, tutto funziona. Così no. Tralasciate errori della funzione inserimento, che ancora devo provare.. quello che mi interessa è capire perchè non compila il programma quando aggiungo nuove funzioni alla libreria? Faccio qualche banalissimo errore di sintassi nella creazione della libreria? Quali nozioni mi sfuggono per la creazione della libreria? (sono autodidatta)
grazie mille per l'attenzione

31 Risposte

  • Re: Creare una libreria con devc - Prime armi

    
    esercizio1.h
    
    char *leggi (char *str);
    
    
    
    esercizio1.c
    
    char *leggi (char *str){
          scanf ("%s",str);
          return (str);
    }
    
    Anche se non è proprio corretto, perchè str non andrebbe ritornato, infatti la tua fuzione dovrebbe essere void, così scritta dovrebbe funzionare.

    Quando invece aggiungi la struct e la funzione di inserimento in lista, hai praticamente dei problemi di compilazione. Perchè la funzione inserimento è scritta male, intanto è una funzione ricorsiva, che ha qualche problema. Scrivere una funzione ricorsiva non è proprio per le prime armi. Prova a spiegare come dovrebbe inserire in lista questa funzione.

    P.s.
    Evita di utilizzare la stessa signature per tutte le variabili, ad esempio il campo str nella struct puoi chiamarlo stringa.
  • Re: Creare una libreria con devc - Prime armi

    Grazie mille per la risposta e per i consigli..
    Tralasciando gli errori di "inserimento" che come dicevo quella è stata solo la prima stesura, i miei dubbi sono dovuti al fatto che, se scrivo un main che utilizza la funzione inserimento, allora compila ma chiaramente l'esecuzione si blocca perchè la funzione inserimento è errata.. Invece con quel main che ho postato che quindi utilizza solo la funzione leggi, mi genera una serie di errori e non mi compila proprio..

    Questo compila:
    #include <stdio.h>
    #include <stdlib.h>
    #include "esercizio1.h"
    
             
    main()
    {
          char *stringa;
          struct listapuntata *lista;
          lista=(struct listapuntata *) malloc(sizeof(struct listapuntata));
          
          printf("Inserire stringa : ");
          leggi(stringa);
          
          lista=inserimento(lista,NULL,stringa);
          
          printf("Il nodo della lista contiene la stringa: %s\n", lista->str);
          system("PAUSE");
          
          }
    
    Invece il programma che ho scritto nel messaggio precendete, e cioè questo
    #include <stdio.h>
    #include <stdlib.h>
    #include "esercizio1.h"
    
           
    main()
    {
          char *stringa;
          stringa=calloc(100, sizeof(char));
          printf ("Digita stringa da leggere: ");
          leggi(stringa);
          printf("\nLa stringa digitata è : %s\n", stringa);
          
          system("PAUSE");
          
          }
    non compila e restituisce questi errori:

    Compilatore: Default compiler
    Esecuzione di gcc.exe...
    gcc.exe "C:\Users\..\esercizio1\1prova.c" -o "C:\Users\..\esercizio1\1prova.exe" -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib"
    In file included from C:\Users\..\esercizio1\1prova.c:3:
    C:\Users\..\esercizio1\/esercizio1.h:15: error: syntax error before '*' token
    C:\Users\..\esercizio1\/esercizio1.h:15: error: syntax error before '*' token

    C:\Users\..\esercizio1\/esercizio1.h: In function `inserimento':
    C:\Users\..\esercizio1\/esercizio1.h:21: error: `lista' undeclared (first use in this function)
    C:\Users\..\esercizio1\/esercizio1.h:21: error: (Each undeclared identifier is reported only once
    C:\Users\..\esercizio1\/esercizio1.h:21: error: for each function it appears in.)
    C:\Users\..\esercizio1\/esercizio1.h:22: error: `str' undeclared (first use in this function)
    C:\Users\..\esercizio1\/esercizio1.h:28: warning: assignment from incompatible pointer type
    C:\Users\..\esercizio1\/esercizio1.h:32: error: `prec' undeclared (first use in this function)

    Esecuzione terminata
  • Re: Creare una libreria con devc - Prime armi

    Ti dispiace copiare sia il .h che il .c che il main che ti da problemi, così che possa farlo girare sul mio pc e controllare.

    Grazie
  • Re: Creare una libreria con devc - Prime armi

    esercizio.h
    
    #ifndef ESERCIZIO_H_INCLUDED
    #define ESERCIZIO_H_INCLUDED
    
    typedef struct listapuntata {
        char *str;
        struct listapuntata *next;
    }listapuntata;
    
    
    listapuntata *inserimento(listapuntata *lista, listapuntata *prec, char *str);
    void leggi (char *str);
    
    #endif // ESERCIZIO_H_INCLUDED
    
    esercizo.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "esercizio.h"
    
    
    void leggi (char *str) {
    
        scanf ("%s",str);
        return;
    }
    
    listapuntata *inserimento(listapuntata *lista, listapuntata *prec, char *str) {
    
        struct listapuntata *nodo, *nuovo;
        nodo=(listapuntata *) malloc(sizeof(listapuntata));
        nuovo= (listapuntata *) malloc(sizeof(listapuntata));
        nodo=lista;
        nuovo->str= str;
    
        if (lista != NULL) {
            if ((strlen(str)) > (strlen(nodo->str))) {
                nodo=inserimento(nodo->next,nodo,str);
            } else {
                nuovo->next=nodo;
                prec->next=nuovo;
            }
        } else {
            nuovo->next=NULL;
        }
    
    
        system("PAUSE");
    
        return lista;
    }
    
    
    main.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "esercizio.h"
    
    #define MAIN1 1
    #define MAIN2 0
    
    
    #if MAIN1 
    int main() {
        char *stringa;
        struct listapuntata *lista;
        lista = (struct listapuntata *) malloc(sizeof(struct listapuntata));
    
        stringa = (char *)calloc(100, sizeof(char));
    
        printf("Inserire stringa : ");
        leggi(stringa);
    
        lista = inserimento(lista, NULL, stringa);
    
        printf("Il nodo della lista contiene la stringa: %s\n", lista->str);
        system("PAUSE");
        return 0;
    
    }
    #endif
    
    
    #if MAIN2 
    int main() {
    
        char *stringa;
        stringa=calloc(100, sizeof(char));
        printf ("Digita stringa da leggere: ");
        leggi(stringa);
        printf("\nLa stringa digitata è : %s\n", stringa);
    
        system("PAUSE");
    
        return 0;
    
    }
    #endif
    
    Adesso compilano tutti e due, ma ovviamente la funzione inserimento non funziona. E' scritta male! Prova a correggerla.
  • Re: Creare una libreria con devc - Prime armi

    A me ora da questo errore...

    [Linker error] undefined reference to `leggi(char*)'
    [Linker error] undefined reference to `inserimento(listapuntata*, listapuntata*, char*)'
    ld returned 1 exit status
  • Re: Creare una libreria con devc - Prime armi

    Nel frattempo sto provando a modificare la funzione inserimento..
    listapuntata *inserimento(listapuntata *lista, char *stringa) {
    
            struct listapuntata *nuovo;
            nuovo= (listapuntata *) malloc(sizeof(listapuntata));
    
            if ( (lista != NULL) && ((strlen(stringa)) > (strlen(lista->str))) )
            {
                    return inserimento(lista->next,stringa);
                
                }
            
            nuovo->str=stringa;
            nuovo->next=lista;
    
    
            system("PAUSE");
    
            return lista;
        }
  • Re: Creare una libreria con devc - Prime armi

    Devi mettere nella directory del progetto sia esercizio.h che esercizio.c!

    Non vede quei file.

    A me compila correttamente con tutte e due le versioni del main.
    Resta solo da correggere la funzione inserimento.
  • Re: Creare una libreria con devc - Prime armi

    Così come l'ho modificata continua a non andare bene?
    Comunque non so quale stupido errore io faccia ma continua a darmi il problema, i due files sono nella stessa directory. Con devc ho creato un progetto libreria, e ha i due file esercizio1.h ed esercizio1.c ..
  • Re: Creare una libreria con devc - Prime armi

    Ho risolto!
  • Re: Creare una libreria con devc - Prime armi

    Ora che ho scritto le funzioni inserimento e cancellazione funzionanti ho un problema con leggi(stringa)... Cioè.. Siano le seguenti le funzioni
    
    listapuntata *inserimento(listapuntata *lista, char *elem)
    {
            if((lista==NULL) || ((strlen(lista->str))>(strlen(elem))))
            {
                    listapuntata *tmp=(listapuntata *)malloc(sizeof(listapuntata));
                    tmp->str=elem;
                    tmp->next=lista;
                    return tmp;
            }
            else{
                    lista->next=inserimento(lista->next,elem);
                    return lista;
            }
    }
    listapuntata *cancella(listapuntata *lista, char *elem)
    {
            int val;
            if (lista!=NULL)
               {
                            val=strcmp((lista->str),elem);
                            
                            if ( val!=0 )
                               {lista->next=cancella(lista->next,elem);}
                            else if (val==0)
                                    { printf("TROVATA\n");
                                    listapuntata *tmp=(listapuntata *)malloc(sizeof(listapuntata));
                                    tmp=lista;
                                    lista=tmp->next;
                                    free(tmp);}
            }
             
             
    return lista;
                
    }

    se nel main la stringa da inserire o cancellare la do con una semplice assegnazione
    stringa="ciao"
    lista=inserimento(lista,stringa)
    
    stringa="ciao"
    lista=cancella(lista,stringa)
    funziona. Se invece scrivo
    leggi(stringa);
    lista=inserimento(lista,stringa);
    non funziona. E in particolare facendo varissimi tentativi mi sono accorta che nel secondo caso, cioè con la funzione leggi, quando entro in inserimento in lista->str mi risulta proprio la stringa che io ho inserito da tastiera, e quindi chiaramente l'inserimento fallisce!
  • Re: Creare una libreria con devc - Prime armi

    Scrivere una libreria, significa delegare alla libreria tutto il lavoro.

    Se la struct l'hai lasciata all'interno del .h allora la struct è vista dal client e questo non va bene in termini di sicurezza. Voglio dire il client, non deve avere accesso a niente della libreria, lui deve poter accedere ad essa solo mediante un hendler.

    Ti suggerisco di allocare all'interno della libreria, in modo da poter fare assegnazioni.
  • Re: Creare una libreria con devc - Prime armi

    Scusami non ho capito molto bene... la struct è all'interno della libreria.. e infatti se inserisco una stringa da tastiera, o tramite assegnazione l'inserimento e la cancellazione all'interno della lista mi funzionano, ho creato anche la funzione stampa per verificare l'aggiornamento dei dati all'interno della lista. Il problema sta nella variabile stringa, e nella funzione leggi..
  • Re: Creare una libreria con devc - Prime armi

    Postami i tre file, per favore. Così che possa controllare.
  • Re: Creare una libreria con devc - Prime armi

    Allora questa è la libreria.. c'è solo un file.h perchè sto creando la libreria statica con devc
    // ESERCIZIO.h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct listapuntata {
        char *str;
        struct listapuntata *next;
    }listapuntata;
    
    
    void leggi (char *str) {
    
         scanf ("%s",str);
         return;
    }
    
    
    
    
    listapuntata *inserimento(listapuntata *lista, char *elem)
    {
            if((lista==NULL) || ((strlen(lista->str))>(strlen(elem))))
            {
                    listapuntata *tmp=(listapuntata *)malloc(sizeof(listapuntata));
                    tmp->str=elem;
                    tmp->next=lista;
                    return tmp;
            }
            else{
                    lista->next=inserimento(lista->next,elem);
                    return lista;
            }
    }
    
    
    void stampa(listapuntata *lista) {
                
                 if (lista != NULL)
                     {
                 printf(" %s\n",lista->str);
                 stampa(lista->next);
                 }
                 else 
                 {
                 return;
                 }
                
    }
    
    listapuntata *cancellatutto(listapuntata *lista)
    {
            if (lista!=NULL)
               lista=cancellatutto(lista->next);
            return lista;
            
            
    }
    
    listapuntata *cancella(listapuntata *lista, char *elem)
    {
            int val;
            if (lista!=NULL)
               {
                            val=strcmp((lista->str),elem);
                            
                            if ( val!=0 )
                               {lista->next=cancella(lista->next,elem);}
                            else if (val==0)
                                    { printf("TROVATA\n");
                                    listapuntata *tmp=(listapuntata *)malloc(sizeof(listapuntata));
                                    tmp=lista;
                                    lista=tmp->next;
                                    free(tmp);}
            }
             
             
    return lista;
                
    }
    
    
    listapuntata *cancellaparticolare(listapuntata *lista, int x, char *a, char *b)
    {
            int val,lung;
            if (lista!=NULL)
               {
                            lung=(strlen(lista->str))-x;
                            
                            if (((lung%2) == 0) && ( (strlen(a)) < (strlen(lista->str)) < (strlen(b))))
                                    { printf("TROVATA\n");
                                      listapuntata *tmp=(listapuntata *)malloc(sizeof(listapuntata));
                                      tmp=lista;
                                      lista=tmp->next;
                                      free(tmp);
                                      
                                    }
                            lista->next=cancellaparticolare(lista->next,x,a,b);
                                    
            }
             
             
    return lista;
                
    }
    
    
    ognuna di queste funzioni funziona.. Il seguente è un esempio di main anche funzionante
    #include <stdio.h>
    #include <stdlib.h>
    #include "ESERCIZIO.h"
    
    int main() {
        
        int i;
        char *stringa,*a, *b;
        struct listapuntata *lista;
        
        
        stringa = (char *)calloc(100, sizeof(char));
        a = (char *)calloc(100, sizeof(char));
        b= (char *)calloc(100, sizeof(char));
        lista=NULL;
        
        /*riga 17____ */ stringa="due";
        lista=inserimento(lista,stringa);
        stringa="amore";
        lista=inserimento(lista,stringa);
        stringa="ciao";
        lista=inserimento(lista,stringa);
        stringa="un";
        lista=inserimento(lista,stringa);
        
        
        system("PAUSE");
        printf("La lista: \n");
        stampa(lista);
        
        printf("Inserisci x: ");
        scanf("%d", &i);
        a="un";
        b="amore";
        
        lista=cancellaparticolare(lista,i,a,b);
        stampa(lista);
        printf("\t\t*****FINE******\n");
        system("PAUSE");
        return 0;
    
    }
    
    cosi funziona tutto.
    Se dove ho aggiunto il commento "riga 17", scrivo leggi(stringa) per appunto dare in input da tastiera la stringa l'esecuzione fallisce.
    E solo dopo numerose prove inserendo all'interno delle funzioni vari printf per verificare i valori delle variabili, mi sono resa conto che in effetti se faccio leggi(stringa) e poi inserimento(lista,stringa), il valore di stringa inserito va in inpunt non solo alla variabile stringa ma anche a lista->str
Devi accedere o registrarti per scrivere nel forum
31 risposte