[C] problema rubrica linguaggio C
Buonasera a tutti, premetto che sono alle prime armi con il linguaggio C. Sto sviluppando un programma che, attualmente, non compila; ho provato ad isolare i seguenti metodi aggiungi_contatto e cerca_contatto che,rispettivamente, devono aggiungere un contatto alla rubrica(che ho realizzato tramite una lista concatenata di contatti) e cercare un contatto(due contatti sono uguali se hanno lo stesso nome) all'interno della rubrica.
Ho scritto il seguente main di prova, per testarli, in cui chiedo all'utente di inserire un contatto nella rubrica chiedendogli i vari campi e salvandoli all'interno della struttura contatto* cont creata. Dopodiché verifico se il contatto appena creato è già presente nella rubrica(tramite il metodo cerca_contatto); se non è presente lo aggiungo(aggiungi_contatto).
Il problema è che aggiungendo più di un contatto nella rubrica, i contatti inseriti non rimangono salvati nella lista che ho creato. Non so se sia un problema del metodo aggiungi_contatto o di stampa_contatti. Qualcuno ha idea di come posso risolvere? Altrimenti potete darmi uno spunto su un metodo alternativo per risolvere il problema?
Ho scritto il seguente main di prova, per testarli, in cui chiedo all'utente di inserire un contatto nella rubrica chiedendogli i vari campi e salvandoli all'interno della struttura contatto* cont creata. Dopodiché verifico se il contatto appena creato è già presente nella rubrica(tramite il metodo cerca_contatto); se non è presente lo aggiungo(aggiungi_contatto).
Il problema è che aggiungendo più di un contatto nella rubrica, i contatti inseriti non rimangono salvati nella lista che ho creato. Non so se sia un problema del metodo aggiungi_contatto o di stampa_contatti. Qualcuno ha idea di come posso risolvere? Altrimenti potete darmi uno spunto su un metodo alternativo per risolvere il problema?
typedef struct contatto{ char nome[STR]; char cognome[STR]; char telefono[TEL]; }contatto; typedef struct list{ contatto * persona; struct list * next; }rubrica; rubrica * r = NULL; void stampa_contatti(rubrica * l){ rubrica * app = l; printf("________________________________________________RUBRICA________________________________________________\n"); while(app != NULL){ contatto * c = app->persona; printf("nome: %s",c->nome); printf("cognome: %s",c->cognome); printf("telefono: %s",c->telefono); printf("\n"); app = app->next; } } int aggiungi_contatto(rubrica ** r,contatto * cont){ rubrica * new_contatto = malloc(sizeof(rubrica)); new_contatto->persona = cont; new_contatto->next = *r; *r = new_contatto; return 0; free(new_contatto); } //ritorna -1 se il contatto non è presente nella rubrica, 0 altrimenti int cerca_contatto(char * n){ if(r == NULL)return -1; while(r != NULL){ contatto * app = r->persona; if(strcmp(app->nome,n) == 0) { return 0; } else r = r->next; } return -1; } int main(){ contatto * cont = NULL; puts("Inserire nuovo contatto? [0:si]/[1:no]"); int ris = write_int(); while(ris == 0){ cont = malloc(sizeof(contatto)); puts("Inserisci nome contatto: "); char nome[STR]; write_sentence(cont->nome,STR); puts("Inserisci cognome: "); char cognome[STR]; write_sentence(cont->cognome,STR); puts("Inserisci numero di telefono: "); char telefono[TEL]; write_sentence(cont->telefono,TEL); if(cerca_contatto(cont->nome) == -1){ printf("contatto non trovato! Inserimento in corso...\n"); aggiungi_contatto(&r,cont); } else { printf("Contatto già esistente!\n"); puts("Nome o numero di telefono già esistente!Riprovare.."); return -1; } stampa_contatti(r); puts("Inserire un altro contatto? [0:si]/[1:no]"); ris = write_int(); } }
Risposte
Perché non metti tutto il codice? Manca la definizione di STR, mancano gli include, manca la definizione di write_int, manca la definizione di write_sentence, e vi sono righe di codici senza senso e con vari errori alla fine.
Inoltre il compilatore ti fornisce un numero notevole di informazioni.
Inoltre il compilatore ti fornisce un numero notevole di informazioni.
Questo è il codice completo. Non posto gli errori del compilatore semplicemente perché non c'è nessun errore in compilazione. Il problema è che non esegue quello che vorrei eseguisse; non riesco a capire se ho sbagliato qualcosa nelle funzioni aggiungi_contatto e cerca_contatto ho se ho sbagliato a scrivere il main.
Il problema fondamentale che ho riscontrato nell'esecuzione è che se aggiungo un nuovo contatto alla lista lo aggiunge e lo stampa bene; appena mi chiede se voglio inserirne un altro e lo inserisco, quando mi stampa la rubrica mi appare solo l'ultimo contatto che ho inserito, come se il primo non l'avesse salvato.
esempio: inserisco
nome:paperino
cognome: de paperinis
telefono: 1234
e mi stampa
______________________RUBRICA_________________
paperino
de paperinis
1234
poi mi chiede se voglio inserirne un altro e lo inserisco
nome: pluto
cognome: de plutis
telefono:2345
A questo punto quando va a stampare, non mi stampa:
______________________RUBRICA_________________
pluto
de plutis
2345
paperino
de paperinis
1234
come vorrei, ma stampa:
______________________RUBRICA_________________
pluto
de plutis
2345
Questo è il problema. Non riesco a capire se ho sbagliato la funzione aggiungi_contatto oppure se sono il main o stampa_contatti a darmi dei problemi.
Il problema fondamentale che ho riscontrato nell'esecuzione è che se aggiungo un nuovo contatto alla lista lo aggiunge e lo stampa bene; appena mi chiede se voglio inserirne un altro e lo inserisco, quando mi stampa la rubrica mi appare solo l'ultimo contatto che ho inserito, come se il primo non l'avesse salvato.
esempio: inserisco
nome:paperino
cognome: de paperinis
telefono: 1234
e mi stampa
______________________RUBRICA_________________
paperino
de paperinis
1234
poi mi chiede se voglio inserirne un altro e lo inserisco
nome: pluto
cognome: de plutis
telefono:2345
A questo punto quando va a stampare, non mi stampa:
______________________RUBRICA_________________
pluto
de plutis
2345
paperino
de paperinis
1234
come vorrei, ma stampa:
______________________RUBRICA_________________
pluto
de plutis
2345
Questo è il problema. Non riesco a capire se ho sbagliato la funzione aggiungi_contatto oppure se sono il main o stampa_contatti a darmi dei problemi.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define STR 32 #define DIM_MSG 32 #define TEL 12 #define MAX_CONTATTI 256 #define DIM_USR 32 typedef struct contatto{ char nome[STR]; char cognome[STR]; char telefono[TEL]; }contatto; typedef struct list{ contatto * persona; struct list * next; }rubrica; rubrica * r = NULL; void stampa_contatti(rubrica * l){ rubrica * app = l; printf("________________________________________________RUBRICA________________________________________________\n"); while(app != NULL){ contatto * c = app->persona; printf("nome: %s",c->nome); printf("cognome: %s",c->cognome); printf("telefono: %s",c->telefono); printf("\n"); app = app->next; } } int write_int(){ int ris = -1; while(1){ char car = getchar(); if(car != '\n') ungetc(car,stdin); char * c; char * buff = NULL; size_t cont = 0; if(getline(&buff,&cont,stdin) > 0){ ris = strtol(buff, &c,0); if(*c == '\n' || *c == '\0'){ break; } else printf("l'input non è un numero intero, riprovare!"); } } return ris; } int write_sentence(char * testo, int len){ int ris; //controllo che non ci sia un carattere newline residuo nello stdin char car = getchar(); if(car != '\n') ungetc(car,stdin);//se è '\n' lo elimino, altrimenti lo reinserisco nello stdin while(1){ char * line = NULL; size_t cont = 0; ris = getline(&line,&cont,stdin); if(ris < len && ris > 0){ //copio la stringa letta in "testo", incluso '\0' strcpy(testo,line); ris--; testo[ris] = '\0'; break; } printf("Stringa troppo lunga [max %d caratteri] o errore nell'inserimento, riprovare", len); } return 0; } int aggiungi_contatto(rubrica ** r,contatto * cont){ rubrica * new_contatto = malloc(sizeof(rubrica)); new_contatto->persona = cont; new_contatto->next = *r; *r = new_contatto; return 0; free(new_contatto); } //ritorna -1 se il contatto non è presente nella rubrica, 0 altrimenti int cerca_contatto(char * n){ if(r == NULL)return -1; while(r != NULL){ contatto * app = r->persona; if(strcmp(app->nome,n) == 0) { return 0; } else r = r->next; } return -1; } int main(){ contatto * cont = NULL; puts("Inserire nuovo contatto? [0:si]/[1:no]"); int ris = write_int(); while(ris == 0){ cont = malloc(sizeof(contatto)); puts("Inserisci nome contatto: "); char nome[STR]; write_sentence(cont->nome,STR); puts("Inserisci cognome: "); char cognome[STR]; write_sentence(cont->cognome,STR); puts("Inserisci numero di telefono: "); char telefono[TEL]; write_sentence(cont->telefono,TEL); if(cerca_contatto(cont->nome) == -1){ printf("contatto non trovato! Inserimento in corso...\n"); aggiungi_contatto(&r,cont); } else { printf("Contatto già esistente!\n"); puts("Nome o numero di telefono già esistente!Riprovare.."); return -1; } stampa_contatti(r); puts("Inserire un altro contatto? [0:si]/[1:no]"); ris = write_int(); } }
Ora è più completa anche se il mio compilatore mi da un warning dicendo che getline non è definita. A ragione dato che l'unica getline che conosco è c++ e contenuta in string (del C++) o in iostream.
Un altro warning che in realtà è un errore è che in aggiungi contatto il free lo hai messo dopo il return.
Inoltre nel main hai definito ma non poi usato le variabili nome, cognome e telefono.
Manca inoltre il codice per distruggere la rubrica.
Ci sono degli errori nella funzione che crea ma devo ancora riuscire a correggerli.
[edit] Mi sono accorto che c'erano molti più problemi nella creazione di quelli che avevo notato prima.
Un altro warning che in realtà è un errore è che in aggiungi contatto il free lo hai messo dopo il return.
Inoltre nel main hai definito ma non poi usato le variabili nome, cognome e telefono.
Manca inoltre il codice per distruggere la rubrica.
Ci sono degli errori nella funzione che crea ma devo ancora riuscire a correggerli.
[edit] Mi sono accorto che c'erano molti più problemi nella creazione di quelli che avevo notato prima.
Ok, getline è gnu C o Posix. L'importante è saperlo; io non lo sapevo.
Ho scoperto perché non trovavo l'errore: non è né nell'aggiunta del contatto né nella visualizzazione. Insomma questo funziona perfettamente:
L'errore è in cerca_contatto. Il problema è che lavori direttamente su r e lo porti alla fine della lista coprendo tutto ciò che c'è prima.
Ho scoperto perché non trovavo l'errore: non è né nell'aggiunta del contatto né nella visualizzazione. Insomma questo funziona perfettamente:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define STR 32 #define DIM_MSG 32 #define TEL 12 #define MAX_CONTATTI 256 #define DIM_USR 32 typedef struct contatto{ char nome[STR]; char cognome[STR]; char telefono[TEL]; }contatto; typedef struct list{ contatto * persona; struct list * next; }rubrica; void stampa_contatti(rubrica * l){ rubrica * app = l; printf("________________________________________________RUBRICA________________________________________________\n"); while(app != NULL){ contatto * c = app->persona; printf("nome: %s\n",c->nome); printf("cognome: %s\n",c->cognome); printf("telefono: %s\n",c->telefono); printf("\n"); app = app->next; } } void aggiungi_contatto(rubrica ** r, contatto * cont){ rubrica * new_contatto = malloc(sizeof(rubrica)); new_contatto->persona = cont; new_contatto->next = *r; *r = new_contatto; } int main(void) { rubrica * r = NULL; rubrica rub[10]; contatto cont[10]; for(int i = 0; i != 10; ++i) { char temp_num[] = { '0'+i, '\0' }; strcpy(cont[i].nome, "Nome"); strcat(cont[i].nome, temp_num); strcpy(cont[i].cognome, "Cognome"); strcpy(cont[i].telefono, "1234"); rub[i] = (rubrica){ cont+i, rub+i+1 }; } rub[9].next = NULL; r = rub; stampa_contatti(r); contatto temp = (contatto){ "Nuovo", "Proprio", "5678" }; aggiungi_contatto(&r, &temp); stampa_contatti(r); }
L'errore è in cerca_contatto. Il problema è che lavori direttamente su r e lo porti alla fine della lista coprendo tutto ciò che c'è prima.