Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] problema con lista di struct

    Ciao a tutti, è la prima volta che scrivo qui, vi prego di perdonare eventuali errori di forma.
    Sto cercando di scrivere un codice per esercitarmi sulle liste dove il campo nodo è di tipo struct. Nello stesso tempo mi esercito ad utilizzare le funzioni e chiaramente usandole senza averne la completa padronanza mi complico la vita. Sono riuscito a scrivere il codice che ora vi posto (anche con l'aiuto della vostra guida in linea) in cui inserisco tramite la funzione ins_elem (che contiene la funzione ins_contact) i vari contatti nella lista, ma quando scelgo di visualizzali tramite la funzione visualizza, mi stampa il numero giusto degli elementi inseriti ma contenenti tutti i dati dell'ultimo contatto dato in input.

    Inserendo i contatti tengo fermo in testa il puntatore p e faccio scorrere il puntatore punt;
    stampando i contatti faccio scorrere il puntatore p che avevo lasciato in testa ma.........


    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    //dichiaro la struttura di ogni contatto della rubrica++++++++++++++++++++++++++
    
    struct contatti {
        char nome[30];
        char cog[30];
        char tel[20];
                     
    }cont;
    
    //dichiaro la struttura della lista+++++++++++++++++++++++++++++++++++++++++++++
    
    struct elemento {
        struct contatti *contatto;             //1 campo costituito dal contatto (struttura completa)
        struct elemento *pun;        //2 campo costituito da un puntatore che punta alla successiva struct elemento
    };
    
    //dichiaro il prototipo della funzione di inserimento dei campi del contatto+++++++++++++++++++
    
    struct contatti *ins_contact();
    
    //dichiaro la funzione di formazione del primo elemento lista completo dei 2 campi (contatti e puntatore)
    
    struct elemento *ins_elem();
    
    //dichiaro la funzione di visualizzazione dei contatti
    
    void visualizza(struct elemento*);
    
    int main(int argc, const char * argv[])
    {
        struct elemento *lista;//dichiarazione della lista (sempre un puntatore )
        lista=ins_elem();      //ora la creo
        char risp[2];
        printf("\nVuoi stampare la lista degli elementi? ");
        scanf("%s",risp);
        if (strcmp(risp,"s")==0) {
            visualizza(lista);
        }else {
            printf("\nCiao");
        }
        
        return 0;
    }
    //funzione ins-elem++++++++++++++++++++++
        
    struct elemento *ins_elem() {
        struct elemento *p,*punt;
        int n,i;
        printf("quanti elementi vuoi inserire in rubrica? ");
        scanf("%d",&n);
        if (n==0) {
            p=NULL;
        }else {
            
            //inserimento primo contatto+++++++++++++++++++++++++++++++++++++++++++++++++++++++
            
            p=(struct elemento*)malloc(sizeof(struct elemento));
            printf("\nInserisci il primo elemento\n");
            ins_contact();
            p->contatto=&cont;
            punt=p;//associo il puntatore che scorrerà la lista 
            
            //creo gli altri elementi+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            for (i=2; i<=n; i++) {
                punt->pun=(struct elemento*)malloc(sizeof(struct elemento));//creo l'altro elemento
                punt=punt->pun;
                printf("\nInserisci il %d elemento\n ",i);
                ins_contact();
                punt->contatto=&cont;
            }
            punt->pun=NULL;
        }
        return p;
    }
    struct contatti *ins_contact() {
        printf("\nInserisci il cognome: ");
        scanf("%s",cont.cog);
        printf("\nInserisci il nome   : ");
        scanf("%s",cont.nome);
        printf("\nInserisci il tel    : ");
        scanf("%s",cont.tel);
        return &cont;
    }
    void visualizza(struct elemento *p) {
        while (p!=NULL) {
            printf("\n %s %s %s ",p->contatto->cog,p->contatto->nome,p->contatto->tel);
            p=p->pun;
        }
        
    }
    ho scritto un codice uguale con il nodo tipo int (studiato sulla vostra guida in linea) e gira benissimo, qui non riesco a capire dove sbaglio: deve esserci un errore nell'inserimento ma non riesco a trovarlo.
    Vi ringrazio in anticipo per l'eventuale dritta.
    P.S. utilizzo xcode

  2. #2
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510
    Usi scorrettamente le funzioni: la funzione ins_contact invece di allocare un elemento, di scriverci sopra e di ritornarlo, usa sempre cont che è una variabile globale.
    Allora tutto viene scritto su quella variabile: cont.
    Ogni volta che dichiari:

    codice:
    punt->contatto=&cont;
    Se dopo questa dichiarazione cambi il valore (cioè i valori dei campi) di cont, anche i valori contenuti in put->contatto cambiano.
    Scrivi la funzione ins_contact correttamente, allocando un elemento e ritornandolo.
    E chiamala correttamente, cioè prendendone il valore di ritorno:

    codice:
    ins_contact(); // non così
    punt->contatto=ins_contact();  // corretto
    Inoltre non stai pulendo il buffer di input (fai una ricerca sul forum per sapere come pulirlo, per evitare i problemi della scanf).

  3. #3
    Ciao,ho dichiarato la variabile cont all'interno della funzione (se è questo che intendevi con "alloca un elemento, utilizzalo e ritornalo")cioè l'ho resa locale, ho chiamato la funzione come mi hai indicato ed ho provveduto a pulire i buffer (anche se non ho ben capito se bisogna pulirli dopo ogni scanf o alla fine dell'inserimento di tutti i campi di cont) ma non ho ottenuto il risultato sperato.
    Allego la parte di codice modificata in modo che puoi darci un'occhiata; se ho frainteso le tue indicazioni ti chiedo di ridarmele in una forma più elementare (sono autodidatta ed è solo 1 mese che ho preso in mano il "C").
    Ho pulito il buffer anche dopo la scanf che memorizza la risposta alla domanda se stampare o meno i contatti.
    Ti saluto e ti ringrazio in anticipo.


    codice:
    struct elemento *ins_elem() {
        struct elemento *p,*punt;
        int n,i;
        printf("quanti elementi vuoi inserire in rubrica? ");
        scanf("%d",&n);
        if (n==0) {
            p=NULL;
        }else {
            
            //inserimento primo contatto+++++++++++++++++++++++++++++++++++++++++++++++++++++++
            
            p=(struct elemento*)malloc(sizeof(struct elemento));
            printf("\nInserisci il primo elemento\n");
            //ins_contact();
            p->contatto=ins_contact();//&cont;
            punt=p;//associo il puntatore che scorrerà la lista 
            
            //creo gli altri elementi+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            for (i=2; i<=n; i++) {
                punt->pun=(struct elemento*)malloc(sizeof(struct elemento));//creo l'altro elemento
                punt=punt->pun;
                printf("\nInserisci il %d elemento\n ",i);
                //ins_contact();
                punt->contatto=ins_contact();//&cont;
            }
            punt->pun=NULL;
        }
        return p;
    }
    struct contatti *ins_contact() {
        struct contatti cont;
        printf("\nInserisci il cognome: ");
        scanf("%s",cont.cog);
        while (getchar()!='\n');
        printf("\nInserisci il nome   : ");
        scanf("%s",cont.nome);
        while (getchar()!='\n');
        printf("\nInserisci il tel    : ");
        scanf("%s",cont.tel);
        while (getchar()!='\n');
        return &cont;
    }

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Non puoi restituire l'indirizzo di una variabile locale.

    In C, all'uscita delle funzioni, le variabili locali vengono distrutte automaticamente e quindi il puntatore non sarebbe valido.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510
    Alloca dinamicamente l' elemento che la ins_contact deve ritornare.

  6. #6
    Ciao e grazie a tutti, ho risolto il problema, ho allocato dinamicamente cont ma ho anche dovuto cambiare la dichiarazione di cont in *cont; ora gira perfettamente!!!

    Se posso approfittare, però, mi sono rimasti 2 dubbi:
    1-il programmino gira ugualmente sia con
    codice:
    punt->contatto=cont;
    che
    codice:
    punt->contatto=ins_contact();
    Qual'è la differenza? perché gira ugualmente?

    2-la deallocazione della memoria è facoltativa? Alla fine della funzione ins_contact ho inserito la free(cont), ma anche senza ottengo lo stesso risultato...

    qual'è l'approccio corretto in entrambi i punti??

    Grazie in anticipo e comunque grazie per l'aiuto nella risoluzione del problema

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da ipspaolo
    1-il programmino gira ugualmente sia con
    codice:
    punt->contatto=cont;
    che
    codice:
    punt->contatto=ins_contact();
    Qual'è la differenza? perché gira ugualmente?
    Dove hai dichiarato il puntatore *cont ? Fuori o dentro la funzione?

    2-la deallocazione della memoria è facoltativa? Alla fine della funzione ins_contact ho inserito la free(cont), ma anche senza ottengo lo stesso risultato...
    Devi liberare la memoria con la free.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    l'ho riportato fuori dove ho dichiarato la struct contatti come era in origine nel listato che ho postato però con l'operatore *.

    2-se non libero la memoria che succede? il programma gira lo stesso!

  9. #9
    Originariamente inviato da ipspaolo
    l'ho riportato fuori dove ho dichiarato la struct contatti come era in origine nel listato che ho postato però con l'operatore *.

    2-se non libero la memoria che succede? il programma gira lo stesso!
    Si ma non rilascia la memoria utilizzata, il sistema la tiene occupata anche se non più in uso, presto o tardi il sistema resterebbe senza memoria e non permetterebbe più ulteriori allocazioni.

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    il programma gira lo stesso!
    Ovviamente gira lo stesso, finché c'è memoria ... quando la memoria termina perché non la liberi, il programma evidenzierà degli errori.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.