[RISOLTO, C] Confronto di elementi all'interno di una lista
Salve ragazzi vi chiedo aiuto a proposito di un programma in c che mi sta facendo uscire pazzo XD
Allora vi scrivo la consegna:
Definire una struttura che permetta di gestire i dati contenuti in un rubrica telefonica.
Creare un programma in linguaggio C che gestisca l’immissione dei dati da tastiera
dei dati della rubrica. Terminare la procedura di immissione dei dati quando si
verifica una di queste condizioni:
⇒ l’informazione per il campo numero è uguale a -1
⇒ il cognome immesso è uguale ad uno precedentemente immesso
=> Salvare la lista su file
Allora vi posto il mio programma
#include
#include
#include
#include
typedef struct rubrica{
char nome[16];
char cognome[16];
char numero[16];
rubrica *next;
}rubrica;
rubrica *Add_to_list(rubrica *head,char nome[],char cognome[],char numero[])
{
rubrica *a;
a=(rubrica*)malloc(sizeof(rubrica));
strcpy(a->nome,nome);
strcpy(a->cognome,cognome);
strcpy(a->numero,numero);
a->next=NULL;
/*if(head==NULL)
return a;*/
a->next=head;
return a;
}
rubrica *Print_list(rubrica *head)
{
int i=0;
printf("Lista: \n");
while(head!=NULL)
{
printf("%d)\nnome:%s\ncognome:%s\nnumero:%s\n",i++,head->nome,head->cognome,head->numero);
head=head->next;
}
}
rubrica *confronto(rubrica *head,char test[])
{
for(;head!=NULL;head=head->next)
{
if(strcmp(head->cognome,test)==0)
break;
}
}
/*rubrica *Search_in_list(rubrica*head,char test[])
{
if(head==NULL)
return NULL;
while(head!=NULL)
{
if (strcmp(head->cognome,test)!=0)
break;
head=head->next;
}
return NULL;
}*/
rubrica Save_to_file(rubrica *head)
{
FILE*fp;
fp=fopen("fname.txt","w");
if(fp!=NULL)
{
while(head!=NULL)
{
fprintf(fp, "nome:%s\ncognome:%s\nnumero telefonico:%s\n",head->nome,head->cognome,head->numero);
head=head->next;
}
}
}
main()
{
rubrica a;
char file[16];
rubrica*head = NULL;
printf("inserisci elementi \n");
strcpy(a.numero,"0");
while(strcmp(a.numero,"-1")!=0 )
{
printf("Nome:");
scanf("%s",a.nome);
printf("Cognome:");
scanf("%s",a.cognome);
printf("Numero di telefono:");
scanf("%s",a.numero);
getchar();
head=Add_to_list(head,a.nome,a.cognome,a.numero);
confronto(head,a.cognome)
}
Print_list(head);
Save_to_file(head);
getchar();
}
Il problema che ho sta nel secondo punto ovvero io ho implementato la funzione per confrontare il campo cognome con quelli precedentemente immessi ma non mi legge il break per fermare il ciclo quando riscontra l'uguaglianza... non so se addirittura non legge la funzione... il resto funziona tutto... tra l'altro la funzione se vedete è esplicata in due modi diversi di cui uno è commentato... anche se penso siano evidentemente equivalenti... grazie in anticipo dell'aiuto
Allora vi scrivo la consegna:
Definire una struttura che permetta di gestire i dati contenuti in un rubrica telefonica.
Creare un programma in linguaggio C che gestisca l’immissione dei dati da tastiera
dei dati della rubrica. Terminare la procedura di immissione dei dati quando si
verifica una di queste condizioni:
⇒ l’informazione per il campo numero è uguale a -1
⇒ il cognome immesso è uguale ad uno precedentemente immesso
=> Salvare la lista su file
Allora vi posto il mio programma
#include
#include
#include
#include
typedef struct rubrica{
char nome[16];
char cognome[16];
char numero[16];
rubrica *next;
}rubrica;
rubrica *Add_to_list(rubrica *head,char nome[],char cognome[],char numero[])
{
rubrica *a;
a=(rubrica*)malloc(sizeof(rubrica));
strcpy(a->nome,nome);
strcpy(a->cognome,cognome);
strcpy(a->numero,numero);
a->next=NULL;
/*if(head==NULL)
return a;*/
a->next=head;
return a;
}
rubrica *Print_list(rubrica *head)
{
int i=0;
printf("Lista: \n");
while(head!=NULL)
{
printf("%d)\nnome:%s\ncognome:%s\nnumero:%s\n",i++,head->nome,head->cognome,head->numero);
head=head->next;
}
}
rubrica *confronto(rubrica *head,char test[])
{
for(;head!=NULL;head=head->next)
{
if(strcmp(head->cognome,test)==0)
break;
}
}
/*rubrica *Search_in_list(rubrica*head,char test[])
{
if(head==NULL)
return NULL;
while(head!=NULL)
{
if (strcmp(head->cognome,test)!=0)
break;
head=head->next;
}
return NULL;
}*/
rubrica Save_to_file(rubrica *head)
{
FILE*fp;
fp=fopen("fname.txt","w");
if(fp!=NULL)
{
while(head!=NULL)
{
fprintf(fp, "nome:%s\ncognome:%s\nnumero telefonico:%s\n",head->nome,head->cognome,head->numero);
head=head->next;
}
}
}
main()
{
rubrica a;
char file[16];
rubrica*head = NULL;
printf("inserisci elementi \n");
strcpy(a.numero,"0");
while(strcmp(a.numero,"-1")!=0 )
{
printf("Nome:");
scanf("%s",a.nome);
printf("Cognome:");
scanf("%s",a.cognome);
printf("Numero di telefono:");
scanf("%s",a.numero);
getchar();
head=Add_to_list(head,a.nome,a.cognome,a.numero);
confronto(head,a.cognome)
}
Print_list(head);
Save_to_file(head);
getchar();
}
Il problema che ho sta nel secondo punto ovvero io ho implementato la funzione per confrontare il campo cognome con quelli precedentemente immessi ma non mi legge il break per fermare il ciclo quando riscontra l'uguaglianza... non so se addirittura non legge la funzione... il resto funziona tutto... tra l'altro la funzione se vedete è esplicata in due modi diversi di cui uno è commentato... anche se penso siano evidentemente equivalenti... grazie in anticipo dell'aiuto

Risposte
Il problema è che il break ti esce dal for, e non ha effetti al di fuori di quella funzione. Dovresti mettere un valore di ritorno a quella funzione in modo da comunicare al resto del mondo che hai trovato il cognome. In ogni caso implementare il tutto con le liste è discutibile: rende la ricerca, che è l'aspetto più importante della rubrica, lineare e non sfrutti neanche il fatto che potresti tenere la lista ordinata al costo di una ricerca. A questo punto con un array dinamico avresti gli stessi svantaggi ma con almeno gli elementi allocati in modo consequenziale. Un metodo migliore è senza dubbio usare un albero anche se converrebbe bilanciarlo.
Purtroppo non posso fare di testa mia perché il professore a ci ha assegnato questo esercizio proprio per utilizzare le liste
in ogni caso io avevo provato a sostituire al break return 1 e poi successivamente implementare all'interno del main con un if ponendo come condizione che la funzione sia uguale a 1 e come comando da svolgere ,nel caso si verificasse la suddetta condizione, il break... in questo momento non ricordo se mi dava un errore sul return 1 o durante l'esecuzione mi permetteva di inserire solo il primo elemento della lista... comunque ricordo che questa implementazione mi dava problemi... tu che ne pensi?

Che se fai return 1 allora confronto dere restituire int e non (rubrica *).
E quindi cosa ci dovrei mettere secondo te?
Beh, intendevo avresti dovuto scriverla così o in modo simile.
mentre nella funzione che lo chiami dovresti usare qualcosa di questo tipo:
P.S.: Il forum possiede un tag code che facilità la lettura del codice. Il suo uso è fortemente consigliano.
int confronto(rubrica *head, char test[]) { int r = 1; for(;(head!=NULL)&&(r != 0);head=head->next) { r = strcmp(head->cognome,test); } return r; }
mentre nella funzione che lo chiami dovresti usare qualcosa di questo tipo:
if(confronto == 0) { /* fai qualcosa */ }
P.S.: Il forum possiede un tag code che facilità la lettura del codice. Il suo uso è fortemente consigliano.
scusami hai ragione per la tag...comunque oggi ho risolto grazie a un amico in facoltà grazie lo stesso
