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.