Logo ITP-NEWS
RSS | Contatti | Login|Registrati| Home
giornali
Rubriche telefoniche con liste concatenate
Di Fusco Francesco::2011-03-17
Condividi questo articolo
Lo scopo di questo articolo Ŕ illustrare la progettazione di un software che gestisca la rubrica telefonica di uno smartphone. Per ogni contatto memorizzato in rubrica, sono presenti: nome, cognome, numero di telefono, indirizzo pagina web personale, indirizzo email.
Le funzioni di gestione da implementare sono almeno: inserimento contatto, ricerca numero contatto, eliminazione contatto, eliminazione di tutta la rubrica, visualizzazione di tutti i contatti.
Ecco il diagramma dei moduli del nostro programma:



I blocchi di livello inferiore sono procedure richiamate dai moduli di livello superiore.

La nostra lista sarÓ costituita da una sequenza di nodi aventi la seguente struttura:



La parte "informativa" del nodo, ovvero la parte che contiene le informazioni relative ad una voce della rubrica (il contatto) avrÓ la seguente struttura:



Dichiariamo la nostra struttura nodo (composta da informazioni + campo puntatore al nodo successivo) nel seguente modo:

struct contatto
{
char nome[25];
char cognome[25];
char telefono[18];
char web[80];
char email[40];
struct contatto *next;
};


Il campo "next" contiene l'indirizzo del prossimo nodo della lista al quale Ŕ collegato:



Per semplificare la dichiarazione del tipo di dato composto contatto usiamo l'istruzione typedef

typedef struct contatto Contatto;
typedef Contatto * ContattoPTR;


in questo modo, quando avremo la necessitÓ di dichiarare una variabile di tipo contatto o un puntatore ad una variabile di tipo contatto, scriveremo semplicemente:

Contatto Cont;
ContattoPtr ContPtr;

invece di scrivere:

struct contatto Cont;
struct contatto * ContPtr;




// RUBRICA TELEFONICA CON LISTE CONCATENATE
/*
* (C) Copyright Di Fusco Francesco 2011-
*/
// Versione 0.3
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#define FILERUBRICA "rubrica.txt"
// Dichiarazione della struttura
typedef struct contatto Contatto;
typedef Contatto * ContattoPTR;

struct contatto
{
char nome[25];
char cognome[25];
char telefono[18];
char web[80];
char email[40];
Contatto *next;
};

// Definizione del tipo Boolean
typedef enum {false,true} boolean;

/*
* Dichiarazione dei prototipi delle funzioni
*/
void menu(Contatto *rubrica);
void stampa_contatto(Contatto p);
void stampa_rubrica(Contatto *p);
Contatto *inserisci_contatto(Contatto *testa, Contatto p);
Contatto leggi_contatto(void);
Contatto *trova_contatto(Contatto *rubrica, char *telefono);
Contatto *inserimento_ordinato(Contatto *testa, Contatto pers);
Contatto *crea_contatto(Contatto p);
Contatto *elimina_contatto(Contatto *testa, char *cognome);
Contatto *cancella_rubrica(Contatto *rubrica);
void salva_rubrica(Contatto *testa);
Contatto *carica_rubrica(char *filename);

// Programma principale
int main()
{
Contatto *rubrica=NULL;// puntatore alla testa della lista della rubrica
menu(rubrica);
return 0;
}

/*
* Legge le informazioni relative ad un contatto in agenda
*/
Contatto leggi_contatto(void)
{
Contatto p;
printf("\nCognome:");scanf("%25s",&p.cognome);
printf("\nNome:");scanf("%25s",&p.nome);
printf("\nTelefono:");scanf("%18s",&p.telefono);
printf("\nweb:");scanf("%80s",&p.web);
printf("\nemail:");scanf("%40s",&p.email);
p.next=NULL;
return p;
}

/*
* Inserimento di un nodo in testa alla lista concatenata
*/
Contatto *inserisci_contatto(Contatto *testa, Contatto p)
{
Contatto *x=NULL;
x=(Contatto *) malloc(sizeof(struct contatto));
if(x!=NULL)
{
strcpy(x-> nome,p.nome);
strcpy(x->cognome,p.cognome);
strcpy(x->telefono,p.telefono);
strcpy(x->web,p.web);
strcpy(x->email,p.email);
x->next=testa;
}
return x; // x sarÓ il puntatore alla nuova testa della lista
}
/*
*Crea un nuovo nodo nella lista concatenata e lo inserisce in testa
*/
Contatto *crea_contatto(Contatto p)
{
Contatto *x=NULL;
x=(Contatto *) malloc(sizeof(struct contatto));
if(x!=NULL)
{
strcpy(x->nome,p.nome);
strcpy(x->cognome,p.cognome);
strcpy(x->telefono,p.telefono);
strcpy(x->web,p.web);
strcpy(x->email,p.email);
x->next=NULL;
}
return x; // x sarÓ il puntatore al nodo appena creato
}
// Stampa un contatto della rubrica
void stampa_contatto(Contatto p)
{
printf("Cognome:\t %s Nome:\t %s Telefono:\t %s web:\t %s email:\t %s\n",p.cognome,p.nome,p.telefono,p.web,p.email);
}
// Stampa tutti i contatti della rubrica
void stampa_rubrica(Contatto *testa)
{
Contatto *q=testa;
while(q!=NULL)
{
stampa_contatto(*q);
q=q->next;
}
}
// Funzione per la ricerca di un contatto tramite il numero telefonico
Contatto *trova_contatto(Contatto *rubrica, char *telefono)
{
Contatto *p=NULL;
boolean trovato=false;
p=rubrica;
while(p!=NULL && trovato==false)
{
if(strcmp(p->telefono,telefono)==0) trovato=true;
else
p=p->next;
}
return p;
}
// Inserimento in una lista ordinata
Contatto *inserimento_ordinato(Contatto *testa, Contatto pers)
{
Contatto *p=NULL, *precPtr=NULL, *corrente=NULL;
precPtr=testa;
corrente=testa;
if(corrente==NULL || strcmp(corrente->cognome,pers.cognome)>=0)
{
testa=inserisci_contatto(testa,pers);// Inserisce il nuovo contatto in testa alla lista
}
else {
while(corrente!=NULL && strcmp(corrente->cognome,pers.cognome)<0)
{
precPtr=corrente;
corrente=corrente->next;
}
p=crea_contatto(pers);// Crea un nuovo nodo da aggiungere alla lista, nel posto opportuno, per mantenere l'ordinamento
p->next=corrente;
precPtr->next=p;
}
return testa;
}
// Elimina un contatto dato un cognome
Contatto *elimina_contatto(Contatto *testa, char *cognome)
{
Contatto *precPtr=NULL,*currPtr=testa, *tmp=NULL;
while(currPtr!=NULL && strcmp(currPtr->cognome,cognome)!=0)
{
precPtr=currPtr;
currPtr=currPtr->next;
}
if (currPtr!=NULL) // L'elemento Ŕ stato trovato nella rubrica
{
tmp=currPtr;
// il record da eliminare Ŕ il primo della lista
if(currPtr==testa)
{
testa=currPtr->next;
}
// Il record da eliminare si trova tra due record
else
precPtr->next=currPtr->next;
}
return (testa);
}
// Elimina tutti i dati della rubrica e restituisce il puntatore NULL
Contatto *cancella_rubrica(Contatto *rubrica)
{
Contatto *currPtr=rubrica,*tmp=NULL;
while(currPtr!=NULL)
{
tmp=currPtr;
currPtr=currPtr->next;
free(tmp);
}
return NULL;
}
void salva_rubrica(Contatto *testa)
{
printf("Sto salvando la rubrica ...\n");
Contatto *ptrRubrica=testa;
FILE *filerubrica=fopen(FILERUBRICA,"w+");
if(filerubrica!=NULL)
{
printf("Il file Ŕ stato correttamente aperto\n");
while(ptrRubrica!=NULL)
{printf("%s %s %s %s %s\n",ptrRubrica->cognome,ptrRubrica->nome,ptrRubrica->telefono,ptrRubrica->web,ptrRubrica->email);
fprintf(filerubrica,"%s %s %s %s %s\n",ptrRubrica->cognome,ptrRubrica->nome,ptrRubrica->telefono,ptrRubrica->web,ptrRubrica->email);
ptrRubrica=ptrRubrica->next;

}
}
else
printf("Errore di apertura del file\n");
fclose(filerubrica);
}
Contatto *carica_rubrica(char *filename)
{
Contatto *ptrRubrica=NULL;
Contatto utente;
FILE *filerubrica=fopen(FILERUBRICA,"r");
if(filerubrica!=NULL)
{
printf("Il file Ŕ stato correttamente aperto\n");
while(!feof(filerubrica))
{
fscanf(filerubrica,"%s %s %s %s %s\n",&utente.cognome,&utente.nome,&utente.telefono,&utente.web,&utente.email);
ptrRubrica=inserimento_ordinato(ptrRubrica,utente);
}
}
else
printf("Errore di apertura del file\n");
fclose(filerubrica);
return ptrRubrica;
}
// Listdelete.c
//FUNZIONE MENU: GESTISCE L'ATTIVAZIONE DELLE VARIE FUNZIONI ATTRAVERSO UN MENU' INTERATTIVO
void menu(Contatto *rubrica)
{
int opz=0;
Contatto p;
Contatto *pers=NULL;
char telefono[18];
char cognome[25];
printf ("*RUBRICA TELEFONICA CON LISTE CONCATENATE*\n");
do{
printf ("\nScegli una delle seguenti opzioni\n");
printf ("1)Inserisci nuovo contatto ........\n");
printf ("2)Cerca un contatto:...............\n");
printf ("3)Elimina un contatto..............\n");
printf ("4)Visualizza rubrica...............\n");
printf ("5)Elimina rubrica..................\n");
printf ("6)Salva rubrica....................\n");
printf ("7)Carica rubrica...................\n");
printf ("8)Esci.............................\n");
printf ("Scelta:............................");
scanf ("%d", &opz);
switch(opz)
{
case 1:
printf("Inserisci contatto\n");
p=leggi_contatto();
rubrica=inserimento_ordinato(rubrica,p);
break;
case 2:
printf ("\nRICERCA CONTATTO\n");
printf("Telefono:"); scanf("%s",&telefono);
pers=trova_contatto(rubrica,telefono);
if(pers!=NULL) stampa_contatto(*pers);
else
printf("Numero inesistente\n");
break;
case 3:
printf ("\nELIMINAZIONE CONTATTO\n");
printf("Cognome:"); scanf("%s",cognome);
rubrica=elimina_contatto(rubrica,cognome);
break;
case 4:
stampa_rubrica(rubrica);
break;
case 5:
// Elimina tutti i nodi della lista (la rubrica) e restituisce il puntatore NULL
rubrica=cancella_rubrica(rubrica);
case 6:
// Salva la rubrica su un file di testo
if(rubrica!=NULL)
salva_rubrica(rubrica);
else
printf("Errore: la lista Ŕ vuota\n");
break;
case 7:
// Carica la rubrica du un file di testo
rubrica=carica_rubrica(FILERUBRICA);
break;
case 8:
printf ("\nUSCITA DAL PROGRAMMA\n");
break;
system ("PAUSE");
default: //stampa a video un messaggio di avviso nel caso in cui si scelga un opzione a cui non corrisponde una funzione
printf ("\nL'OPZIONE NON E' SUPPORTATA.\n");
}
}while (opz!=8);
}
Documenti allegati:
gestione_rubrica_liste.c

Invia questo articolo ad un amico

Nome Mittente
Email Mittente
Nome Destinatario
Email Destinatario
Messaggio

Free Web Hosting with Website Builder

Gli ultimi articoli


Java e array -- ricerca di un elemento in un array
Array in Java
Gestione dei file in Php
Protocollo ARP
Come convertire caratteri in Ascii in Java
Conversione di un numero da stringa ad intero e viceversa
Tabella di struct - memorizzare i conti ed i nomi dei clienti
Un esempio di struct in C
In tutta Italia il "sabato del pinguino" festa di Linux e del software Libero
Inserimento di un elemento di un insieme S, che verifica una certa proprietÓ P, in un secondo insieme T
Webmaster
Home
Condizioni d'utilizzo
Privacy
Mappa del sito
Contattateci
(C) Teaching OnLine (Napoli) - 2009