Errore strcmp

di Anonimizzato15378 il
40 risposte
Sia data la struttura
typedef struct abr {
    char *str;
    struct abr *sx;
    struct abr *dx;
}abr;
e la funzione
ABR abr_insert(ABR t, char *elem)
{
     if (t!=NULL)
     {
           
           if (strcmp(elem,t->str)<0) t->sx=abr_insert(t->sx,elem);
           else if (strcmp(elem,t->str)>0) t->dx=abr_insert(t->dx,elem);
                             
           return t;  }
           
     else 
           {
                  ABR nodo=(abr *)malloc(sizeof(abr));
                  nodo->str=elem;
                  nodo->sx=NULL;
                  nodo->dx=NULL;
                  return nodo;
                  }   
}
come mai scritta cosi la funzione NON funziona, mentre se al posto di strcmp utilizzo dei confronti con strlen, si?

40 Risposte

  • ABR com'è definito?
  • Come mi avevi detto per listapuntata nel precedente post, così ho fatto tutto uguale per abr.. mi funziona tutto.. anche l'inserimento ma solo le uso strlen, avevo lo stesso problema con le listepuntate.. penso che ho proprio un problema con strcmp! XD
    abr.c :
    //abr.c
    
    typedef struct abr * ABR;
    char * leggi (void);
    ABR abr_insert(ABR t, char *elem);
    void abr_stampa(ABR t);
    ABR abr_svuota(ABR t);
    ABR abr_cancel(ABR t, char *elem);
    ABR abr_staccamin(ABR p_t, ABR t);
    
    abr.h
    // abr.h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "abr.h"
    
    typedef struct abr {
        char *str;
        struct abr *sx;
        struct abr *dx;
    }abr;
    
    char * leggi (void) {
        char *s = (char *)malloc(80*sizeof(char));
        scanf ("%s",s);
        return s;
    }
    
    ABR abr_insert(ABR t, char *elem)
    {
         if (t!=NULL)
         {
              
               if (strlen(elem)<=strlen(t->str)) t->sx=abr_insert(t->sx,elem);
               else t->dx=abr_insert(t->dx,elem);
                                 
               return t;  }
               
         else 
               {
                      ABR nodo=(abr *)malloc(sizeof(abr));
                      nodo->str=elem;
                      nodo->sx=NULL;
                      nodo->dx=NULL;
                      return nodo;
                      }   
    }
         
    void abr_stampa(ABR t)
    {
         if (t!=NULL)
         {
            if (t->sx!=NULL) abr_stampa(t->sx);
            
            printf("%s\n",t->str);
            
            if(t->dx!=NULL) abr_stampa(t->dx);
            }
         
         else return;
    }
    
    ABR abr_svuota (ABR t)
    {
         if(t!=NULL) 
         {
              if(t->dx!=NULL) 
                   t->dx=abr_svuota(t->dx);
              else if(t->sx!=NULL) 
                   t->sx=abr_svuota(t->sx);
         
         }
         
         else return t;
    }
    
    ABR abr_cancel(ABR t, char *elem)
    {
        if (t!=NULL)
        {
                    if ((strlen(elem))<(strlen(t->str))) t->sx=abr_cancel(t->sx,elem);
                    else if ((strlen(elem))>(strlen(t->str))) t->dx=abr_cancel(t->dx,elem);
                    else if ((strcmp(elem,t->str)) == 0 )
                         { 
                         ABR tmp=(abr *)malloc(sizeof(abr));
                         tmp=t;
                         if(tmp->sx == NULL) t=tmp->dx;
                         else if (tmp->dx == NULL) t=tmp->sx;
                         else 
                         {    tmp=abr_staccamin(t,t->dx);
                              strcpy(t->str,tmp->str);
                              }
                         
                         free(tmp);
                         }
        }
        
        return t;
    }
    
    ABR abr_staccamin(ABR p, ABR t)
    {
        if (t!=NULL)
        {
                    if (t->sx!=NULL) return abr_staccamin(t,t->sx);
                    else
                    {
                        if (t=p->sx) p->sx=t->dx;
                        else p->dx=t->dx;
                        }
        }
        
    return t;
    }
    main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "abr.h"
    
    
    int main()
    {
        int esci=0, scelta=11, continua;
        ABR albero=NULL;
        char *stringa,striga1,stringa2;
        char risp;
        int x;
        
        while(!esci){
                    switch(scelta){
                            case 1: 
                                 printf("Inserisci stringa: ");
                                 stringa=leggi();
                                 albero=abr_insert(albero,stringa);
                                 printf("Digita 1 per tornare al menu principale, o qualsiasi tasto per uscire.\n");
                                 scanf("%d",&continua);
                                 if (continua==1) scelta=11;
                                 else esci=1;
                                 break;
                            case 2:
                                 if(albero!=NULL) abr_stampa(albero);
                                 else printf("Abr vuoto.\n");
                                 printf("Digita 1 per tornare al menu principale, o qualsiasi tasto per uscire.\n");
                                 scanf("%d",&continua);
                                 if (continua==1) scelta=11;
                                 else esci=1;
                                 break;   
                            case 3:
                                 if (albero!=NULL) 
                                 {  albero=abr_svuota(albero);
                                    printf("Abr svuotato.\n");
                                    }
                                 else printf("Abr gia' vuoto.\n");
                                 
                                 printf("Digita 1 per tornare al menu principale, o qualsiasi tasto per uscire.\n");
                                 scanf("%d",&continua);
                                 if (continua==1) scelta=11;
                                 else esci=1;
                                 break;
                            case 4:
                                 if (albero==NULL) printf("Abr vuoto.");
                                 else
                                 {   printf("Quale stringa vuoi cancellare? ");
                                     stringa=leggi();
                                     albero=abr_cancel(albero,stringa);
                                    }
                                 printf("Digita 1 per tornare al menu principale, o qualsiasi tasto per uscire.\n");
                                 scanf("%d",&continua);
                                 if (continua==1) scelta=11;
                                 else esci=1;
                                 break;
                            case 5:
                                 printf("\nInserisci due strighe entro le quali vuoi sia compreso il valore di quella\nda eliminare (in ordine crescente):\n1) ");
                                 stringa1=leggi();
                                 printf("2) ");
                                 stringa2=leggi();
                                 printf("Se vuoi eliminare una stringa di lunghezza pari, digita un numero pari, \naltrimenti digita un numero dispari: ");
                                 scanf("%d", &x);
                                 printf("Sono state eliminate, perche' rispecchiano i criteri scelti, le stringhe: ");
                                 albero=abr_cancellaparidispari(albero,x,stringa1,stringa2);
                                 
                                 printf("Digita 1 per tornare al menu principale, o qualsiasi tasto per uscire.");
                                 scanf("%d",&continua);
                                 if (continua==1) scelta=10;
                                 else esci=1;
                                 break;
                            case 9: 
                                 esci=1;
                                 break;
                            case 11: 
                                 printf("\n\t\t**************** MENU ****************\n\n");
                                 printf("1) Aggiungi una stringa all'abr.\n");
                                 printf("2) Stampa contenuto abr.\n");
                                 printf("3) Svuota abr.\n");
                                 printf("4) Cancella un nodo dall'abr.\n");
                                 printf("5) Cancella una stringa con lunghezza pari o dispari, e con valore \n   compreso tra due stringhe scelte.\n");
                                 printf("9) Esci. \n\n\n");
                                 printf("\nInserisci la tua scelta: ");
                                 scanf("%d%*c",&scelta);
                                 break;    
                            /*case :
                                 printf("Scelta non valida");
                                 scelta=11;
                                 break;*/
                                 }
                            }
        printf("\nBye!\n");
        system("PAUSE");
        return 0;
    
        
    }
    
    Il precedente è tutto il codice funzionate, ma se la funzione inserimento la sostituisco con questa usando quindi strcmp non funziona più
    ABR abr_insert(ABR t, char *elem)
    {
         if (t!=NULL)
         {
               
               if (strcmp(elem,t->str)<0) t->sx=abr_insert(t->sx,elem);
               else if (strcmp(elem,t->str)>0) t->dx=abr_insert(t->dx,elem);
                                 
               return t;  }
               
         else
               {
                      ABR nodo=(abr *)malloc(sizeof(abr));
                      nodo->str=elem;
                      nodo->sx=NULL;
                      nodo->dx=NULL;
                      return nodo;
                      }   
    }
  • In questo momento non posso mettere il codice sul PC.

    Vi viene di consigliarti di controllare che sia str che elem sono stringhe, hanno il\0?
  • Le stringhe le inserisco da tastiera con scanf
    char * leggi (void) {
        char *s = (char *)malloc(80*sizeof(char));
        scanf ("%s",s);
        return s;
    }
  • La scanf dovrebbe aggiungere il terminatore.

    Puoi dirmi che errore hai?
  • Non inserisce le stringhe in ordine
  • se al posto di strcmp utilizzo dei confronti con strlen
    Non capisco cosa intendi ... strcmp e strlen non fanno la stessa cosa ... non puoi usare una al posto dell'altra ...
  • Proviamo a stampare il valore di ritorno della strcmp. Cerchiamo di capire dov'è il problema.
  • Ti ho inserito sia il codice con strlen che con strcmp proprio per essere più chiara..
  • Adesso non posso metterelo sul PC. Prova a vedere che valore hai all'interno degli if.
  • Intanto i due codici sono logicamente diversi. Quante volte usi la strlen in

    if (strlen(elem)<=strlen(t->str)) t->sx=abr_insert(t->sx,elem);
    else t->dx=abr_insert(t->dx,elem);

    ?

    E quante volte la strcmp in

    if (strcmp(elem,t->str)<0) t->sx=abr_insert(t->sx,elem);
    else if (strcmp(elem,t->str)>0) t->dx=abr_insert(t->dx,elem);

    ?

    Perché questa differenza? Secondo te può avere importanza? E se sì, perché?
  • Con strlen confronto anche le stringhe di uguale lunghezza, mentre con strcmp faccio solo un confronto se una s1 è minore o maggiore di s2.. per come ho scritto io il codice, ma l'ho fatto di proposito.
    Ma se voglio verificare l'uguaglianza delle stringhe così come ho fatto nella funzione cancella.. strcmp(..,..)==0 funziona... è quando verifico se sia minore o maggiore di 0 che non funziona.. non può essere dovuto a qualcosa che abbia a che fare con i puntatori piuttosto che con le stringhe?
  • Rifaccio la domanda ... nel caso le due stringhe siano eguali (con la strcmp), quale insert esegui?
  • Come tu dici la strlen ritorna la lunghezza di due strighe, ovvero:

    strlen(pippa); //ritorna 5
    strlen(pippo); //ritorna 5

    mentre la strcmp ritorna l'ordine alfabetico di due stringhe seguendo il codice ASCII, infatti

    strcmp(pippo, pippa); //ritorna -1, cioè la stringa pippo segue la stringa pippa
    strcmp(pippo, pippo); //ritorna 0, cioè le stringhe sono uguali
    strcmp(pippa, pippo); //ritorna 1, cioè la stringhe pippa precede la stringa pippa
Devi accedere o registrarti per scrivere nel forum
40 risposte