Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di Syntax
    Registrato dal
    Oct 2003
    Messaggi
    18

    [C] Problema lista dinamica

    Ciao,

    dovrei creare una rubrica telefonica utilizzando le liste dinamiche...

    il problema è che la parte relativa alla cancellazione di un elemento della lista non mi vuole assolutamente funzionare...

    scusatemi se è già stato postato da qualche parte, ma mi son letto tutti i post sulle liste senza trovare niente di utile...

    teoricamente mi sembra corretto, ma in pratica non funziona


    Vi posto il codice che fino ad ora ho scritto, provate a cancellare un elemento selezionandolo per nome, perchè a me proprio non va...

    le funzioni interessate sono

    struct node * delete_node ( struct node * current_node );
    void delete_element ( struct node * current_node );

    grazie!

    e scusatemi se sono proprio un , ma C l'ho iniziato a studiare da un mese...

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    /* Define boolean Type */
    
    typedef enum { false, true } boolean;
    
    /* Definisco i campi che dovrà memorizzare la mia rubrica per ogni contatto */
    
    typedef struct {
        
        int id;
        char nome[50];
        char cognome[50];
        char telefono[14];
        char citta[20];
        char email[50];
        char indirizzo[20];
       
    
    } contatto;
    
    /* Definisco il singolo elemento della rubrica */
    
    struct node {
        
         contatto content;
         struct node * next_node;
        
    };
    
    /* Creo la rubrica e la inizializzo */
    
    struct node * rubrica = NULL;
    
    
    /* Prototipi funzioni */
    
    struct node * add_contact( struct node * current_node );
    
    struct node * delete_node ( struct node * current_node );
    void delete_element ( struct node * current_node );
    
    void show_contact( struct node * current_node );
    
    
    contatto get_data( void );
    
    /* Prototipi Procedures // GUI */
    
    void gui_table_line () ;
    void gui_table_space () ;
    void print_element ( contatto contatto_temp );
    void print_delete_menu ();
    
    /* Prototipi funzioni // STRINGHE */
    boolean string_compare( char * s1, char * s2 );
    
    
    
    
    /* Variabili globali */
    
    int contact_counter = 0;
        
    
    
    /* Rubrica */
    
    int main() {
       
     int i; 
    
    
     /* Inserisco 3 valori per vedere se mi funziona la cancellazione in seguito... */
     for ( i=0; i<2; i++ ) {
         
          rubrica = add_contact( rubrica );    
    
     } 
     
    
     show_contact( rubrica );
     
    
     delete_element( rubrica ); 
     
     show_contact( rubrica );
    
     getch();
     
     return 0;
    
    }
    
    
    
    
    
    
    /* Raccogli dati per inserimento/modifica */
    
    contatto get_data () {
        
        contatto contatto_temp;
        
        contatto_temp.id = contact_counter;
        
        contact_counter++;
        
        printf ( "\n\nSTEP 1: Inserire il nome del contatto\n>>");
        gets ( contatto_temp.nome );
        
        printf ( "\nSTEP 2: Inserire il cognome\n>>");
        gets ( contatto_temp.cognome );
        
        printf ( "\nSTEP 3: Inserire il numero telefonico\n>>");
        gets ( contatto_temp.telefono );
        
        printf ( "\nSTEP 4: Inserire l'indirizzo\n>>");
        gets ( contatto_temp.indirizzo );
        
        printf ( "\nSTEP 5: Inserire la citta'\n>>");
        gets ( contatto_temp.citta );
        
        printf ( "\nSTEP 6: Inserire l'indirizzo email\n>>");
        gets ( contatto_temp.email );
        
        return contatto_temp;
        
    }    
    
    /* Aggiungi node alla rubrica. L'elemento è aggiunto in testa. */
    
    struct node * add_contact( struct node * current_node ) {
           
        struct node *temp_node;   
           
        contatto contatto_temp;
        
        
        
        /* Acquisisco i dati da tastiera e li salvo in una struttura temporanea */
            
        contatto_temp = get_data();
        
        /* Alloco la memoria per il nuovo node da inserire in rubrica */
        
        temp_node = malloc( sizeof ( struct node ) );
            
        temp_node->content = contatto_temp;
            
        
        /* Aggiungo i riferimenti all'elemeno successivo */
        
        temp_node->next_node = current_node;
    
        return temp_node;   
        
    }   
    
    
    /* Visualizza elementi presenti in rubrica */
    
    void show_contact( struct node *current_node ) { 
        
        
         while ( current_node != NULL ) {
             
             print_element ( current_node->content );
    
             current_node = current_node->next_node;
             
             
         }    
             
    }   
    
    /* Cancella un node */
    
    void delete_element ( struct node * current_node ) {
       
       /* Cursore ricerca */ 
       struct node * temp_node;
       
       
       /* Variabile contenente codice operazione */
       char action;       
       
       /* Variabile di conferma operazioni -> Contiene Y (true) o N (false) */
       char confirm;     
       
       /* Contatore cancellazioni eseguite */
       int counter = 0;  
       
       /* Variabile temporanee per confrontare stringhe */
       char stringa_temp[50];
       char stringa_temp_current_node[50];
       
       
       
       
       /* Menu di selezione */
       print_delete_menu ();
        
        
        
       /* Acquisisci operazione da effettuare */
       printf ( "\n\n>" );
       scanf ( "%c%*c" , &action );
       
       switch ( action ) {
           
              /* CANCELLA PER NOME */
           
              case '1' :
                  
                  /* Acquisisci il nome da ricercare e cancellare */
                  printf ( "\n\n NOME >" );
                  gets( stringa_temp );
                  
                  
                  /* Conferma cancellazione */
                  printf ( "\n\nSei sicuro di cancellare dalla rubrica tutti gli elementi contenenti %s nel campo nome? [Y/N] >" , stringa_temp);
                  scanf ( "%c%*c" , &confirm );
                  
                  confirm = tolower( confirm );
                  
                  if ( confirm != 'y' )   break;
                  
                  
                  /* Scorri current_node e cancella elementi corrispondenti */  
                  
                  while ( current_node != NULL ) {
                       
                       /* Assegna il campo da confrontare nella current_node alla stringa temporanea */
                       strcpy( stringa_temp_current_node , current_node->content.nome );     
                       
                       
                       /* Confronta e cancella se positivo */
                       if ( string_compare( stringa_temp , stringa_temp_current_node ) ) {
                          
                              
                          current_node = delete_node ( current_node );
                                                 
                           
                          
                       } else {
                          
                           current_node = current_node->next_node;    
                         
                       }    
                       
                    
                      
                  }    
                   
                  printf ( "\n Eseguite %d cancellazioni...Premere un tasto per continuare" , counter );
                  
                  
              break;    
               
           
       }   
       
    
    }
    
    /* Cancella un node, riassegna gli indirizzi e libera la memoria allocata non più utilizzata */
    
    struct node * delete_node ( struct node * current_node ) {
           
       struct node * temp_node;
           
       temp_node = current_node->next_node;
       
       free ( current_node );
       
       return temp_node;
    
    }
    
    /* STRING FUNCTIONS */
    
    
    boolean string_compare( char * s1, char * s2 ) {
    
        if ( strcasecmp( s1, s2 ) )
    
            return false;
    
        else
    
            return true;
        
    
    }
    
    
    /* GUI ELEMENTS */
    
    
    /* Stampa il menu per cancellare elementi  */
    
    void print_delete_menu () {
        
        
        gui_table_line ();
        
        gui_table_space ();
        
        printf ( "\n|          SELEZIONA ELEMENTO DA CANCELLARE PER:            |" );
        
        gui_table_space ();
        
        gui_table_line ();
        
        gui_table_space ();
        
        printf ( "\n|  1. NOME                                                  |" );
        printf ( "\n|  2. COGNOME                                               |" );
        printf ( "\n|  3. ID                                                    |" );
        printf ( "\n|  4. NUMERO TELEFONO                                       |" );
        
        gui_table_space ();
        
        gui_table_line ();
        
        
    }
    
    /* Stampa un contatto a schermo */
    
    void print_element ( contatto contatto_temp ) {
        
        gui_table_line ();
        
        gui_table_space ();
        printf ( "\n|                  CONTATTO %d                               " , contatto_temp.id);
        gui_table_space ();
        
        gui_table_line ();
        
        gui_table_space ();
        printf ( "\n                  |" );
        printf ( "\n Cognome:         |    %s  " , contatto_temp.cognome);
        printf ( "\n Nome:            |    %s  " , contatto_temp.nome);
        printf ( "\n Telefono:        |    %s  " , contatto_temp.telefono);
        printf ( "\n Indirizzo:       |    %s  " , contatto_temp.indirizzo);
        printf ( "\n Città:           |    %s  " , contatto_temp.citta);
        printf ( "\n Email:           |    %s  " , contatto_temp.email);
        printf ( "\n                  |" );
        gui_table_space ();
        
        gui_table_line ();   
    
    } 
    
    
    /* Stampa una linea per le tabelle */
    
    void gui_table_line () {
        
         printf ( "\n+-----------------------------------------------------------+" );   
    
    }
    
    /* Stampa una linea vuota con bordi per le tabelle */
    
    void gui_table_space () {
        
         printf ( "\n|                                                           |" );   
    
    }
    |Syntax|

  2. #2
    Utente di HTML.it L'avatar di Syntax
    Registrato dal
    Oct 2003
    Messaggi
    18
    up!


    nn c'è proprio nessuno che ha la voglia di guardarlo

    sò che è un po' lunghetto il codice, ma la parte che dovete guardare è solo quella relativa alle funzioni



    struct node * delete_node ( struct node * current_node );

    void delete_element ( struct node * current_node );
    |Syntax|

  3. #3
    Utente di HTML.it L'avatar di Ed_Bunker
    Registrato dal
    Jul 2003
    Messaggi
    1,119
    Ance a me serve una liksta dinamica che metta a disposizione le operazioni di inserzione, cancellazione, ricerca di un elemento e restituzione degli elelemnti presenti. Allega il sorgente.c che dopo gli do un'occhiata. Quali sono le procedure che ti creano problemi ? In fase di compilazione tutto ok ?

  4. #4
    Utente di HTML.it L'avatar di Syntax
    Registrato dal
    Oct 2003
    Messaggi
    18
    copai e incolla il codice che il sorgente è tutto sopra compilazione tutto ok, funzionare funziona, solo che non cancella gli elementi...
    |Syntax|

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2003
    Messaggi
    423

    2 problemi

    Allora:
    1) La tua funzione di confronto di stringhe è sbagliata: strcasecmp() restituisce ZERO se sono uguali, VALORI POSITIVI se s1 è lessicograficamente maggiore di s2, VALORI NEGATIVI se s2 è lessicograficamente maggiore di s1. Da riscrivere.
    2) Anche quando questo funzionerà, il tuo codice darà violazione d'accesso alla prima prova. Infatti, rifletti. Nel momento in cui tu cancelli una voce, non modifichi il puntatore che c'era nella voce precedente che puntava alla voce appena cancellata. Risultato ? Un puntatore ad una zona di memoria deallocata -> crash. Mi sa che ti conviene avere sia un *next_node che un *prev_node.

  6. #6
    Utente di HTML.it L'avatar di Syntax
    Registrato dal
    Oct 2003
    Messaggi
    18
    uhm allora riguardo al punto 1:

    la funzione è corretta

    codice:
    boolean string_compare( char * s1, char * s2 ) {
    
        if ( strcasecmp( s1, s2 ) )
    
            return false;
    
        else
    
            return true;
        
    
    }
    infatti, se strcasecmp restituisce valori diversi da 0 (ossia le stringhe non sono uguali )ritorno false, se restisce zero ( ossia le stringhe sono uguali ) allora restituisco true.

    riguardo al punto due, hai ragione, è che non riesco proprio a capire come scriverla corretta...almeno, teoricamente mi sembra sia giusta, ma poi in pratica...

    vabbè ci proverò...
    |Syntax|

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2003
    Messaggi
    423
    Giusto, giusto ... Ieri era tardi, mi sono confuso. Comunque secondo me fai meglio ad usare uno strcmp, e scriverti una piccola funzione che ti manda a lowercase tutte e 2 le stringhe, perchè 'sto strcasecmp non mi sembra sia standard ... Comunque devi verificare se in effetti quando lui "scorre" la lista, cancella effettivamente delle voci. Mettici un [cout << "Sto cancellando"], così ti rendi conto.

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2003
    Messaggi
    423
    potresti usare una cosa del genere per portare a lowercase le stringhe:
    codice:
    char *tolow(char *s)
    {
    	char *temp = new char;
    	int i;
    	for(i = 0; i<strlen(s); i++) *(temp+i) = tolower(*(s+i));
    	temp[i] = '\0';
    	return temp;
    }
    E poi fare uno strcmp(tolow(s1), tolow(s2)); Così usi solo funzioni della libreria standard. Ti ripeto: verifica se in effetti il programma lancia il tuo delete node. In caso positivo, potrebbe essere successo questo: tu hai deallocato la memoria, ma nessun processo l'ha ancora intaccata, per cui i dati sono ancora integri. Quando vai a scorrere la lista, i puntatori che ti portano a scorrere le voci puntano ancora a quelle zone di memoria e quindi è come se la lista fosse ancora intatta. In ogni caso, per il tuo problema basta creare un puntatore *prev_node che punti al nodo precedente ed è fatta.

  9. #9
    Utente di HTML.it L'avatar di Syntax
    Registrato dal
    Oct 2003
    Messaggi
    18
    uhm, hai ragione, meglio usare funzioni standard... però la tua funzione per convertire in minuscolo non mi funziona...

    mi fà crashare il programma...

    l'ho provata anche da sola così, ma non va, crasha sempre. Cosa significava il new char, quando avevi scritto char * temp = new char; ?? Il compilatore me lo segnala come errore...

    Scusami per le domande, magari ti sembrano davvero banali, ma sto impazzendo su sto cavolo di problema...

    codice:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    char * tolow( char * s );
    
    int main () {
        
     char * prova;
     
     strcpy ( prova , "ASFASKFQglhasfeASG3" );
     
     printf ( "%s", prova );
     
     prova = tolow( prova );
     
     printf ( "%s", prova );
        
     getch();
     
     return 0;   
     
    }
    
    char *tolow(char *s)
    {
    	char *temp;
    	int i;
    	for(i = 0; i<strlen(s); i++) *(temp+i) = tolower(*(s+i));
    	
    	i++;
    	temp[i] = '\0';
    	return temp;
    	
    }
    per la lista invece sono quasi alla soluzione credo, usando il puntatore come mi hai suggerito al nodo precedente...
    |Syntax|

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2003
    Messaggi
    423
    L'errore lo da perchè alla fine del ciclo for ci hai messo quell'istruzione
    codice:
    i++;
    che non c'entra nulla. Per il
    codice:
    new char
    Scusa mi sono sbagliato, è c++. L'istruzione che devi mettere tu è
    codice:
    char *temp = (char*)malloc(sizeof(s))

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.