PDA

Visualizza la versione completa : [C] Rubrica telefonica con le liste linkate


mi&ni
04-01-2011, 17:30
salve a tutti sono nuovo del forum ed ho un problema con questo programma se qualcuno mi potesse aiutare mi farebbe un grosso piacere

questo è il programma


#include <stdio.h>
#include <iostream>
#include <string.h>
typedef struct
{
char Nome[30]; //nome del contatto
char Cognome[30]; //cognome del contatto
char Tel[30]; //numero di telefono del contatto
char Indirizzopaginaweb[50]; //indirizzo di pagina web
char Indirizzoemail[50];
} Contatto;

struct elemento
{
Contatto inf;
struct elemento *pun;
};

void visualizzaContatto(struct elemento* p)
{
if (p == NULL)
{
/* Se non ci sono contatti lo stampo a video*/
printf (" # VISUALIZZA CONTATTO #\n");
printf (" Nessun contatto presente\n");
} else {
/*Stampo il primo contatto presente*/
printf (" # VISUALIZZA CONTATTO #\n");
printf (" NOME > %s\n", p->inf.Nome);
printf (" COGNOME > %s\n", p->inf.Cognome);
printf (" TELEFONO > %s\n", p->inf.Tel);
printf (" SITOWEB > %s\n", p->inf.Indirizzopaginaweb);
printf (" EMAIL > %s\n", p->inf.Indirizzoemail);
}
while (p != NULL)
{
/* Stampo gli altri contatti*/
printf (" # VISUALIZZA CONTATTO #\n");
printf (" NOME > %s\n", p->inf.Nome);
printf (" COGNOME > %s\n", p->inf.Cognome);
printf (" TELEFONO > %s\n", p->inf.Tel);
printf (" SITOWEB > %s\n", p->inf.Indirizzopaginaweb);
printf (" EMAIL > %s\n", p->inf.Indirizzoemail);
// Leggo l'elemento successivo
p = p->pun;
}
}

struct elemento *aggiungiContatto(struct elemento *p)
{
printf (" # AGGIUNGI CONTATTO #\n");
// Dichiaro le variabili
char nome[50];
char cognome[50];
char telefono[30];
char email[100];
char sitoweb[200];
Contatto daInserire;
struct elemento *punt;
// Popolo la variabile daInserire
printf (" NOME > ");
scanf ("%s", nome);
strcpy(daInserire.Nome, nome);
printf (" COGNOME > ");
scanf ("%s", cognome);
strcpy(daInserire.Cognome, cognome);
printf (" TELEFONO > ");
scanf ("%s", telefono);
strcpy(daInserire.Tel, telefono);
printf (" SITOWEB > ");
scanf ("%s", sitoweb);
strcpy(daInserire.Indirizzopaginaweb, sitoweb);
printf (" EMAIL > ");
scanf ("%s", email);
strcpy(daInserire.Indirizzoemail, email);

if(p != NULL)
{
/* creazione elementi successivi */
// Alloco la memoria necessaria
punt = (struct elemento *)malloc(sizeof(struct elemento));
// Metto daInserire nell'informazione del puntatore
punt->inf = daInserire;
// Metto il puntatore in testa alla lista
punt->pun = p;

} else {
/* creazione primo elemento */
// Alloco la memoria necessaria
p = (struct elemento *)malloc(sizeof(struct elemento));
// Metto daInserire nell'informazione del puntatore
p->inf = daInserire;
// p punta a NULL, ovvero il marcatore di fine lista
p->pun = NULL;
// Assegno p a punt
punt = p;
}
// Esce dalla funzione e restituisce la lista
return(punt);
}
struct elemento *rimuoviContatto(struct elemento *p)
{
// Dichiaro le variabili
struct elemento *aus;
struct elemento *twin = p;
int subscelta;
int i=1;
int n=1;
// Stampo la schermata
printf (" # RIMUOVI CONTATTO #\n");
// Stampo la lista di contatti
while (p != NULL)
{
printf ("%i) \t %s \t %s\n", i, p->inf.Nome, p->inf.Cognome);
p = p->pun; // scorre di un elemento
i++;
}
// Ottengo il valore originario di p
p = twin;
// Scelgo l'emento da eliminare
printf("\n\n Inserisci il numero del contatto che vuoi rimuovere: ");
scanf("%i", &subscelta);
if (subscelta < i)
{
// Se la lista èvuota esco
if(p == NULL)
return 0;
// Se la lista ha almeno due elmenti...
if(p->pun != NULL)
{
// ... inizializzo un puntatore ausiliario ...
aus=p;
n++;
// ... e faccio un ciclo per trovare l'elemento da eliminare ...
while(n != i)
{
// Trovato l'elemento gli faccio puntare l'oggetto puntato dal suo
// puntatore, in poche parole "salto" l'elemento da eliminare
if(subscelta == n)
{
aus->pun=aus->pun->pun;
} else {
// Nel caso in cui il puntatore fosse NULL, per non creare casini
// glielo assegniamo direttamente
aus=aus->pun;
}
n++;
}
}
/*Se si vuole rimuovere il primo elemento, si assegna
* a p il valore del suo oggetto puntato; questo accade quando subscelta == 1*/
if(subscelta == 1)
{
p=p->pun;
}
}
// Copia di nuovo il valore p modificato in twin
twin = p;
// Esce dalla funzione e restituisce la lista
return twin;
}


void cerca(struct elemento *p){
int n;
int i;
int s=14;
char c[100];
struct elemento ;
printf("dammi il cognome che stai cercando\n");
scanf("%s",&c);
for (i=0;i<n;)
if(strcmp(c,p->inf.Cognome)!=atoi(p->inf.Cognome)){
printf("il cognome trovato è:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",p->inf.Nome,p->inf.Cognome,p->inf.Tel,p->inf.Indirizzopaginaweb,p->inf.Indirizzoemail);
system("PAUSE");
break;
}else if(strcmp(c,p->inf.Cognome)!=atoi(p->inf.Cognome)){
printf("riprovaci:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",p->inf.Nome,p->inf.Cognome,p->inf.Tel,p->inf.Indirizzopaginaweb,p->inf.Indirizzoemail);
system("PAUSE");
break;
}else{
printf("\nERRORE: nessun elemento corrisponde a quello che stai cercando\n\n");
system("PAUSE");
break;
}}

int main()
{
// dichiaro la variabile scelta e la lista vuota
int scelta;
struct elemento *lista = NULL;
{
// Stampo il menu
do
{
printf (" 1) VISUALIZZA CONTATTO\n\n");
printf (" 2) AGGIUNGI CONTATTO\n\n");
printf (" 3) RIMUOVI CONTATTO\n\n");
printf (" 4) CERCA CONTATTO\n\n");
printf (" 5) ESCI\n\n\n\n");
printf (" la tua scelta > ");
scanf("%d",&scelta);
system("CLS");
switch(scelta)
{
case 1: // Visualizzo i contatti presenti
{
visualizzaContatto(lista);
break;
}
case 2: // Aggiungo un nuovo contatto
{
lista = aggiungiContatto(lista);
break;
}
case 3:
{
lista = rimuoviContatto(lista);
break;
}
case 4:
{
lista = cerca(lista);
break;
}
system("PAUSE");
system("CLS");
}}while(scelta!=5);
return 0;
}}


mi da un errore in questa stringa e poi volevo chiedervi se questo codice va bene perchè secondo me la funzione cerca mi dara dei problemi mi potete dare dei consigli
lista = cerca(lista);


grazie in anticipo per le vostre risposte

ramy89
04-01-2011, 18:22
Non è indentato bene comunque in che riga ti da l' errore?

mi&ni
04-01-2011, 18:26
void value not ignored as it ought to be


mi da questo errore e mi segnala questa stringa

lista = cerca(lista);


cmq mi puoi dare quelche consiglio per implementarlo meglio il programma

ramy89
04-01-2011, 20:45
Innanzitutto includi l' header iostream del c++.
Poi inf.cognome non esiste,tu hai dichiarato una struttura globale che si chiama elemento.
Se la tua intenzione è accedere al cognome devi chiamare il nome della variabile dichiarata come Contatto,ad esempio:



Contatto alfa;
strcmp(c,alfa.cognome)
...


Poi nella scanf usi %s per memorizzare un singolo carattere quando in realtà va usato %c.
Poi apparte gli errori di sintassi come punti e virgola dimenticati,sul mio coompilatore segnala che la variabile s della void cerca è inutilizzata.
Un' altra cosa è che la funzione cerca è void,per puntarla devi dichiarare un puntatore a void.

Un consiglio che ti do è che se hai un compilatore che non ti dice le righe dove ci sono gli errori,ne andrebbe installato un altro.
Io uso mingw32 con code::blocks.
Un suggerimento per farla migliore è dichiarare gli elementi come Nome e Cognome dei puntatori a char e poi allocare la memoria necessaria a contenerli.
Io per fare ciò ho creato una funzione apposita che prendendo un puntatore prende da input la stringa,alloca la memoria necessaria a aggiunge il terminatore.
Mi ricordo anche che c' erano dei modi per migliorarla ma l' ho lasciata così per ora.
Eccola qua: http://pastebin.com/yuFAJqwH

mi&ni
05-01-2011, 15:51
ok grazie mille per il tuo aiuto adesso ti posto il codice corretto

allora devo aggiungere questa libreria

#include <iostream>

poi mettere il puntatore alla funzione void

void *cerca(struct elemento *p){


inizzializzare una variabile di tipo Conttatto

Contatto as;

e modificare l'if

if(strcmp(c,as.Cognome)!=atoi(as.Cognome)){

poi ti ringrazio per la funzione che mi hai scritto ma visto che questo è un progetto di esame non posso utilizzare funzioni che non abbiamo studiato nel corso

ah poi nella scanf ho profato ha cambiare lettera come mi hai detto tu pero quando eseguo non mi fa immettere il nome della variabile mi stampa direttamente la printf

in conclusione ecco la mia funzione


void *cerca(struct elemento *p){
int n;
int i;
char c[100];
Contatto as;
printf("dammi il cognome che stai cercando\n");
scanf("%s",&c);
for (i=0;i<n;)
if(strcmp(c,as.Cognome)!=atoi(as.Cognome)){
printf("il cognome trovato è:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",p->inf.Nome,p->inf.Cognome,p->inf.Tel,p->inf.Indirizzopaginaweb,p->inf.Indirizzoemail);
system("PAUSE");
break;
}else if(strcmp(c,as.Cognome)!=atoi(as.Cognome)){
printf("riprovaci:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",p->inf.Nome,p->inf.Cognome,p->inf.Tel,p->inf.Indirizzopaginaweb,p->inf.Indirizzoemail);
system("PAUSE");
break;
}else{
printf("\nERRORE: nessun elemento corrisponde a quello che stai cercando\n\n");
system("PAUSE");
break;
}}

pero mi da un problema che mi stampa solo il primo elemento dell'array qualsiasi nome metto
scusami per tutti questi fastidi

ramy89
05-01-2011, 15:58
Anche io ho l' esame di C tra 10 giorni,mi sa che una funzione del genere la fa usare solo se gliela sai scrivere,ma ovvimanete bisogna saperla a memoria.
Fai prima col metodo che stai usando allora.
Comunque in che riga stai tentando di stampare?

mi&ni
05-01-2011, 16:08
allora buona fortuna per l'esame io ho il 17 l'esame

cmq il problema dovrebbe trovarsi in queste stringhe


printf("dammi il cognome che stai cercando\n");
scanf("%s",&c);
for (i=0;i<n;)
if(strcmp(c,as.Cognome)!=atoi(as.Cognome)){
printf("il cognome trovato è:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",p->inf.Nome,p->inf.Cognome,p->inf.Tel,p->inf.Indirizzopaginaweb,p->inf.Indirizzoemail);
system("PAUSE");
break;


quando eseguo il programma queste sono le uniche stringhe che mi esegue qualsiasi sia il nome che metto

ramy89
05-01-2011, 16:36
Te una volta che hai n strutture nella ram basta tenere il punatore alla prima e all' ultima struttura,oppure il numero di strutture che hai e il puntatore alla prima.
Poi inizi a cercare il cognome,scandisci tutte le strutture con un ciclo:


for(i=0;i<num;i++)
{
if(!strcmp(ptr[i].cognome,c))
//stampi tutti gli elementi della struttura
}

Se vuoi prendere una lista di strutture s stampare i cognomi che ti interessano devi usare un ciclo per fare le comparazioni.Se ho capito bene il cognome è contenuto in c,che è una stringa.
A questo punto se hai il puntatore alla struttura e conosci il numero di strutture,ti basta fare le comparazioni e stampare solo le strutture che ti interessano.

Celebron
05-01-2011, 16:52
Faccio una domanda non prettamente legata a questo programma ma alle linked list in se

Ho ripreso in mano una vecchia libreria che avevo fatto proprio sulle linked list, e ho notato la funzione di ordinamento che non mi convince proprio

la dovrei aver sicuramente sviluppata basandomi su quanto suggeriva il Sedgewick in merito, visto che era quello il manuale di algoritmi legato al corso. Nella pratica si basa su una lettura di tutta la lista individuando ogni volta l'elemento minore e attaccandolo ad una seconda lista ausiliaria. Sebbene questo porti a non dare problemi di memoria (aggiunge semplicemente un putantore testa temporaneo) a mio parere, essendo una sorta di selection sort, per grandi moli di dati diventa troppo lento.
Ora sebbene sia consapevole che le liste di solito andrebbero usate quando non sono previsti numerosi ordinamenti, mi chiedevo se fosse da privilegiare una risoluzione di questo genere (la lista è formata da node_t*nodo che contengono i campi item_t*obj e node_t*next):
converto temporaneamente la lista in un vettore di item_t*, mentre durante la creazione del vettore faccio il free() dei vari nodi in modo che l'occupazione di memoria resti pressoché uguale (anzi, risparmio la memoria dedicata ai puntatori a next dei node_t*), quindi lancio un quicksort sul vettore e infine ricompongo la lista liberando la memoria occupata dal vettore

Alla fin fine avrei un costo in termini di tempo n+1 costante dato dalla creazione del vettore e dalla sua distruzione, riducendo però la complessità dell'ordinamento da n^2 a n*log(n). In questo caso il costo costante aggiuntivo dovrebbe risultare trascurabile.
Ho sbagliato qualcosa?

mi&ni
05-01-2011, 17:02
ok ho capito ho aggiustato il for e pure l'if ho provato ad aggiustare la printf levandolo come puntatore pero adesso mi stampa simboli senza senso

ecco con le modifiche



void *cerca(struct elemento *p){
int n;
int i;
char c[100];
elemento as;
printf("dammi il cognome che stai cercando\n");
scanf("%s",&c);
for (i=0;i<n;i++){
if(!strcmp(c,as.inf.Cognome));
}
printf("il cognome trovato è:\n");
printf("nome %s \ncognome %s\ntelefono %s\npagina web %s\nemail %s\n\n",as.inf.Nome,as.inf.Cognome,as.inf.Tel,as.inf.Indi rizzopaginaweb,as.inf.Indirizzoemail);
system("PAUSE");
}

cmq grazie per l'aiuto che mi stai dando

in altenativa mi converebbe scrivere questa funzione in modo diverso?
se si come la scrivo?

Loading