Eliminare elementi da una lista in C

di il
4 risposte

Eliminare elementi da una lista in C

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.
/*****************************************************************************************************/
/* 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.



Un'idea sul problema ce l'avrei, ma non riesco a risolverlo.. Sapreste essermi di aiuto? Grazie mille.

4 Risposte

  • Re: Eliminare elementi da una lista in C

    Ma perché elimini gli elementi dalla lista per visualizzarli? Non ha senso
  • Re: Eliminare elementi da una lista in C

    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?
  • Re: Eliminare elementi da una lista in C

    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.
  • Re: Eliminare elementi da una lista in C

    Mmm.. no, effettivamente non posso darti torto, ma quello non è il problema più grande del mio programma.. Ho risolto il problema della lista, ma ne ho notati altri..Ad esempio, nel momento in cui inserisco più di 4 numeri nel momento in cui mi viene richiesto, quelli in più vengono giudicati come nome del dispositivo, ma non riesco a capire perchè.. Invece se inserisco un nome più grande di 10, giustamente, il programma va in overflow ed esce.. Che tipo di controllo potrei mettere qui? Avevo pensato di usare la funzione strlen, ma non va bene perchè il programma non ci arriva neanche a quella riga di codice nel momento in cui viene inserita una stringa non valida. Grazie.
Devi accedere o registrarti per scrivere nel forum
4 risposte