Eliminare elementi da una lista in C

Forum di discussioni su C e C++

Moderatore: Toki

Regole del forum
Leggi: IProgrammatori.it - Regolamento Forum
Royzh
New Entry
Messaggi: 2
Iscritto il: 12 gen 2018, 16:03

Eliminare elementi da una lista in C

Messaggioda Royzh » 12 gen 2018, 16:52

Salve a tutti, sto riscontrando un problema nella progettazione di una funzione, mi spiego meglio.
Il mio programma chiede all'utente di inserire una serie di indirizzi numerici nella forma m.n.p.q e il nome del dispositivo associato e deve stampare a video tutti gli insiemi di nomi di dispositivi che sono nella stessa rete locale (ovvero se hanno m e n uguali), ma la funzione che ho implementato per confrontare questi indirizzi mi sta dando non pochi problemi. Qui di seguito vi riporto il codice.

Codice: Seleziona tutto

/*****************************************************************************************************/
/* Programma che stampa a video gli insiemi di nomi di dispositivi che sono nella stessa rete locale */
/*****************************************************************************************************/

/*****************************/
/* Inclusione delle librerie */
/*****************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/************************************/
/* Definizione della struttura dati */
/************************************/

typedef struct elem_lista
{
   int         m,            /* Primo elemento della rete */
            n,            /* Secondo elemento della rete */
            q,            /* Terzo elemento della rete */
            p;            /* Quarto elemento della rete */
   char         nome_simbolico[10+1];      /* Nome della rete */
   struct   elem_lista   *succ_p;         /* Puntatore all'elemento successivo */
}reti_t;

/********************************/
/* Dichiarazione delle funzioni */
/********************************/
void metti_in_coda(reti_t **,
         reti_t **,
         int,
         int,
         int,
         int,
         char*);
void visita_lista(reti_t *);
void confronta_lista(reti_t **);

/* Definizione della funzione main */
int main(void)
{
   /* Definzione delle variabili locali alla funzione */
   int    m,         /* Input: Primo elemento della rete */
          n,         /* Input: Secondo elemento della rete */
          p,         /* Input: Terzo elemento della rete */
          q;         /* Input: Quarto elemento della rete */
   int   esito_lettura;      /* Lavoro: Controllo di ritorno per la funzione scanf */
   int    valido=1;       /* Lavoro: Variabile flag. 0 se il valore non è un candidato ad essere stampato, 1 se lo è */
            
   char    nome_simbolico[10+1];   /* Input: Nome della rete associato all'indirizzo */

   reti_t    *testa_p=NULL;      /* Lavoro: Testa della lista */
   reti_t    *coda_p=NULL;      /* Lavoro: Coda della lista */
   
   printf("Per terminare l'inserimento digitare '-1' quando viene richiesto l'indirizzo e FINE quando viene richiesto il nome.\n\n");
   
   /* Validazione stretta sfruttando il risultato della funzione scanf */
   do
   {   
      /* Chiedo all'utente di inserire una serie di indirizzi numerici */
      do
      {
         printf("\nInserire un indirizzo nella forma m.n.p.q, dove m,n,p e q sono dei numeri interi.\n");
         esito_lettura =scanf("%d.%d.%d.%d",
                          &m,
                    &n,
                    &p,
                    &q);
         if (esito_lettura != 4)
         {
            printf("Input non accettabile!\n");
            valido = 0;
            while (getchar() != '\n');
         }   
         else
            valido = 1;
      }
      while (esito_lettura != 4 && m != -1);
      
      /* Chiedo all'utente di inserire il corrispettivo nome simbolico */
      do
      {
         printf("Inserisci il corrispettivo nome del dispositivo.\n");
         esito_lettura = scanf("%10s",
                      nome_simbolico);
         if (esito_lettura != 1)
         {
            printf("Input non accettabile!\n");
            valido = 0;
            while (getchar()  != '\n');
         }
         else
            valido = 1;
      }
      while (esito_lettura != 1);
      
      
      /* Controllo se sono stati inseriti i valori "sentinella" per uscire dall'inserimento */
      if((m == -1) && (strcmp(nome_simbolico, "FINE") == 0))
         valido = 0;
      if(valido == 1)               /* Se la variabile valido == 1, vuol dire che posso inserire quegli elementi nella lista */
         /* Utilizzo la funzione metti_in_coda per riempire la lista */
         metti_in_coda(&testa_p,
                  &coda_p,
                            m,
                          n,
                         p,
                         q,
                            nome_simbolico);

   }
   while((m != -1) && (strcmp(nome_simbolico, "FINE")!= 0));
   
   /* Una volta riempita la lista facciamo una stampa di verifica */
   printf("\nStampo la lista:\n");
   visita_lista(testa_p);
   /* Nel caso in cui non ci siano stati inserimenti... */
   if(testa_p == NULL)
      printf("La lista e' vuota!\n");      /*... avvertire l'utente che la lista è vuota */
   
   /* Confrontiamo gli elementi della lista per vedere quali sono nella stessa rete */
   printf("\nConfronto gli elementi della lista:\n");
   /* Nel caso in cui non ci siano stati inserimenti... */
   if(testa_p == NULL)
      printf("Non c'è nulla da confrontare, non ci sono elementi nella lista!\n");   /*... avvertire l'utente che il programma non può confrontare nulla */
   /* In caso contrario... */
   else   
      confronta_lista(&testa_p);      /*... eseguire la funzione */
   
   return(0);
}

/* Definizione della funzione metti_in_coda */

void metti_in_coda(reti_t **testa_p,
         reti_t **coda_p,
         int       m,
         int      n,
         int      p,
         int      q,
         char*   nome_simbolico)
{
   /* Dichiarazione delle variabili locali alla funzione */
   reti_t    *nuovo_p;

   nuovo_p = (reti_t *)malloc(sizeof(reti_t));   /* Alloco dinamicamente il nuovo elemento */
   nuovo_p->m = m;               
   nuovo_p->n = n;
   nuovo_p->p = p;
   nuovo_p->q = q;
   strcpy(nuovo_p->nome_simbolico, nome_simbolico);
   nuovo_p->succ_p = NULL;            /* Poniamo il puntatore all'elemento successivo del nostro elemento = NULL */
   if (*coda_p != NULL)            /* Se la coda è diversa da NULL, allora... */
      (*coda_p)->succ_p = nuovo_p;      /* ... */
   else                  /* Se la coda è NULL, allora... */
       *testa_p = nuovo_p;         /* Assegno alla testa della lista il nuovo elemento */
   *coda_p = nuovo_p;            
}



/* Definizione della funzione visita_lista */
void visita_lista(reti_t *testa_p)
{

   /* Dichiarazione delle variabili interne alla funzione */
   reti_t *elem_p;

   for (elem_p = testa_p;
        (elem_p != NULL);
        elem_p = elem_p->succ_p)
      printf("%d.%d.%d.%d\t%s\n",
         elem_p->m,
         elem_p->n,
         elem_p->p,
         elem_p->q,
         elem_p->nome_simbolico);
}
/* Definizione della funzione confronta_lista */
void confronta_lista(reti_t **testa_p)
{
   /* Dichiarazione delle variabili locali */
   reti_t  *prev_p,         
      *curr_p,
      *app_p;
   int    moved;            /* Lavoro: */

   while((*testa_p)->succ_p != NULL)
   {
      moved = 0;
   /* Assegno primo elemento della rete */   
      prev_p = app_p = *testa_p;
      curr_p = prev_p->succ_p;

      printf("\nNella rete %d.%d ci sono:\n", prev_p->m, prev_p->n);
      printf("%s\n",prev_p->nome_simbolico);

      while(curr_p != NULL)
      {
         /* Confronto se l'indirizzo successivo appartiene alla rete */
         if ((app_p->m == curr_p->m) && (app_p->n == curr_p->n))         
         {
            printf("%s\n",curr_p->nome_simbolico);         
            prev_p->succ_p = curr_p->succ_p;
         }
         else                           /* Altrimenti... */
         {
            if (moved == 0)
            {
               *testa_p = curr_p;               /*... aggiorno il valore della testa della lista */
               moved = 1;
            }
         }
         prev_p = curr_p;
         curr_p = curr_p->succ_p;      
      }
   }
   
   if (testa_p != NULL)
   {
      prev_p = *testa_p;
      printf("\nNella rete %d.%d ci sono:\n", prev_p->m, prev_p->n);
      printf("%s\n", prev_p->nome_simbolico);

   }
   *testa_p = (*testa_p)->succ_p;
}


La funzione incriminata è ovviamente "confronta_lista". Praticamente il programma funziona relativamente, cioè, in alcuni casi il programma non elimina gli elementi dalla lista, così che viene ristampato più volte un indirizzo con le sue reti locali.

Immagine

Un'idea sul problema ce l'avrei, ma non riesco a risolverlo.. Sapreste essermi di aiuto? Grazie mille.
oregon
Utente Senior
Messaggi: 10308
Iscritto il: 20 nov 2011, 18:54

Re: Eliminare elementi da una lista in C

Messaggioda oregon » 13 gen 2018, 18:34

Ma perché elimini gli elementi dalla lista per visualizzarli? Non ha senso
___________________
"Il gioco del Lotto : la tassa sull'imbecillità". (Bruno De Finetti, grande matematico italiano)
Royzh
New Entry
Messaggi: 2
Iscritto il: 12 gen 2018, 16:03

Re: Eliminare elementi da una lista in C

Messaggioda Royzh » 13 gen 2018, 18:57

oregon ha scritto:Ma perché elimini gli elementi dalla lista per visualizzarli? Non ha senso

La funzione confronta la testa con tutti gli altri elementi della lista. Se sono nella stessa rete locale stampa il nome del dispositivo e lo elimina dalla lista, così che al ciclo successivo, quando la testa sarà aggiornata, gli elementi di quella rete non ci sono più.. perchè non dovrebbero essere eliminati?
oregon
Utente Senior
Messaggi: 10308
Iscritto il: 20 nov 2011, 18:54

Re: Eliminare elementi da una lista in C

Messaggioda oregon » 13 gen 2018, 19:03

Perché così non hai più i dati !

Hai mai visto un programma che fa l'elenco di alcuni dati e subito dopo non li ha più perché li ha cancellati !?

Devi solo trovare il metodo per visualizzare i dati come richiesto, non cancellarli.
___________________
"Il gioco del Lotto : la tassa sull'imbecillità". (Bruno De Finetti, grande matematico italiano)

Torna a “C/C++”

Chi c’è in linea

Visitano il forum: Nessuno e 46 ospiti