PDA

View Full Version : [C]Lista lineare che non và


devil_prince
02-07-2011, 11:47
Ragazzi devo creare questa lista lineare completa di menù per inserimento, eliminazione e visualizzazione della lista. Per ora ho implementato l'inserimento in testa e la visualizzazione, ma mi danno dei problemi. Provando col debbagger è come se la function dell'inserimento in testo non aggiornasse i puntatori dopo aver inserito l'elemento...vi passo il codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct persona{
char nome[20];
struct persona *p_next;} Persona;


void insl_testa(char [] , Persona **);
void insl_nodo(char [] , Persona **);
void print_lista(Persona *);
void main ()
{
int op, menu=100;
Persona *head, *punt;
char dato[20];
head=NULL;//creiamo la lista
while (menu<=100){
puts("\n\n\n=======================");
puts("GESTIONE DI UNA LISTA");
puts("=======================\n\n");
puts("Selezionare l'operazione:\n");
puts("1=Visualizzare la lista");
puts("2=Inserire un elemento");
puts("3=eliminare un elemento");
scanf("%d",&op);

switch (op) {
case 1: print_lista(&head); break;
case 2 : printf("Inserie il nuovo nome: ");scanf("%s",dato);
insl_testa(dato,&head);
/*else {
printf("Inserie il nuovo nome: ");scanf("%s",dato);
insl_nodo(dato,&punt);} break;*/

}
}
}
void insl_testa (char dato[20], Persona **p_head)
{
Persona *ptr;
ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
ptr->nome[20]=dato[20];//assegna alla nuova memoria allocata il nuovo nodo
ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
*p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
}
void insl_nodo(char dato[20], struct persona **p_punt)
{
struct persona *ptr;
ptr=calloc(1,sizeof(struct persona));
ptr->nome[20]=dato[20];
ptr->p_next=(*p_punt)->p_next;
(*p_punt)->p_next=ptr;
*p_punt=ptr;
}
void print_lista(Persona *pl)
{
printf("\n\n");
printf("lista: ");
while (pl){
printf("%s\n", pl->nome[20]);
pl = pl->p_next;
}
printf("\n\n");
}

tuccio`
02-07-2011, 13:04
ptr->nome[20]=dato[20];//assegna alla nuova memoria allocata il nuovo nodo

forse quello che intendevi era questo?


strncpy(ptr->nome, dato, 19);
ptr->nome[19] = '\0'; // strncpy non assicura che ci sia il terminatore

devil_prince
02-07-2011, 13:18
no infatti mi sono accorto anche io di questo errore, ora ho fatto due struct così posso usare '=' come assegnazione
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct info{
char nome[20];} Info;
typedef struct persona{
Info info;
struct persona *p_next;} Persona;


void insl_testa(Info , Persona **);
void insl_nodo(char [] , Persona **);
void print_lista(Persona *);
void main ()
{
int op, menu=100;
Persona *head, *punt;
Info dato;
head=NULL;//creiamo la lista
while (menu<=100){
puts("\n\n\n=======================");
puts("GESTIONE DI UNA LISTA");
puts("=======================\n\n");
puts("Selezionare l'operazione:\n");
puts("1=Visualizzare la lista");
puts("2=Inserire un elemento");
puts("3=eliminare un elemento");
scanf("%d",&op);

switch (op) {
case 1: print_lista(&head); break;
case 2 : printf("Inserie il nuovo nome: ");scanf("%s",dato.nome);
insl_testa(dato,&head); break;
/*else {
printf("Inserie il nuovo nome: ");scanf("%s",dato);
insl_nodo(dato,&punt);} break;*/

}
}
}
void insl_testa (Info dato, Persona **p_head)
{
Persona *ptr;
ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
ptr->info=dato;//assegna alla nuova memoria allocata il nuovo nodo
ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
*p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
}
/*void insl_nodo(char dato[20], struct persona **p_punt)
{
struct persona *ptr;
ptr=calloc(1,sizeof(struct persona));
ptr->nome[20]=dato[20];
ptr->p_next=(*p_punt)->p_next;
(*p_punt)->p_next=ptr;
*p_punt=ptr;
}*/
void print_lista(Persona *pl)
{
printf("\n\n");
printf("lista: ");
while (pl){
printf("%s\n", pl->info);
pl = pl->p_next;
}
printf("\n\n");
}
solo che ho ancora problemi quando stampo la lista...mi stampa solo l'ultimo nome che ho inserito e poi subito dopo <null>

tuccio`
02-07-2011, 13:33
ops niente letto male

ps:


printf("%s\n", pl->info);


eseguendo il tuo codice, ma stampando pl->info.nome invece di pl->info funziona, onestamente non me lo saprei spiegare, visto che non mi sembra sensato il padding di una struct che contiene un array di char, però va be' :asd:

devil_prince
02-07-2011, 13:44
ops niente letto male

scusa, che significa?

tuccio`
02-07-2011, 14:01
scusa, che significa?che avevo risposto, ma avevo letto la parte commentata del codice e non posso deletare i post :asd:

comunque ho editato sopra, leggi

devil_prince
02-07-2011, 14:16
ho editato come dici tu, ma non funzione ancora, mi stampa dei caratteri casuali
http://www.divshare.com/img/15218802-e95.jpg

tuccio`
02-07-2011, 14:22
ah, avevo dimenticato


case 1: print_lista(&head); break;


questo l'hai editato in print_lista(head) ?

devil_prince
02-07-2011, 14:38
Ok ultima versione...ho aggiunto anche il campo eta, ma mi crasha quando inserisco le informazioni con la scanf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct persona{
char nome[20];
short eta;
struct persona *p_next;} Persona;


void insl_testa(char [] , short , Persona **);
void insl_nodo(char [] , short, Persona **);
void print_lista(Persona *);
void main ()
{
int op, menu=100;
Persona *head, *punt;
char dato_n[20]; short dato_e;
head=NULL;//creiamo la lista

while (menu<=100)
{
puts("\n\n\n=======================");
puts("GESTIONE DI UNA LISTA");
puts("=======================\n\n");
puts("Selezionare l'operazione:\n");
puts("1=Visualizzare la lista");
puts("2=Inserire un elemento");
puts("3=eliminare un elemento");
scanf("%d",&op);

switch (op)
{
case 1: print_lista(head); break;

case 2 :if (head==NULL){
printf("Inserie il nuovo nome: ");scanf("%s",dato_n);
printf("Inserie l'eta': ");scanf("%d",dato_e);
insl_testa(dato_n,dato_e,&head); break;}
else{
printf("Inserie il nuovo nome: ");scanf("%s",dato_n);
printf("Inserie l'eta': ");scanf("%d",dato_e);
insl_nodo(dato_n,dato_e,&punt); break;}
}
}
}
void insl_testa (char dato_n[20], short dato_e, Persona **p_head)
{
Persona *ptr;
ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
strcpy(ptr->nome,dato_n);//assegna alla nuova memoria allocata il nuovo nodo
ptr->eta=dato_e;
ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
*p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
}
void insl_nodo(char dato_n[20], short dato_e, struct persona **p_punt)
{
struct persona *ptr;
ptr=calloc(1,sizeof(struct persona));
strcpy(ptr->nome,dato_n);
ptr->eta=dato_e;
ptr->p_next=(*p_punt)->p_next;
(*p_punt)->p_next=ptr;
*p_punt=ptr;
}
void print_lista(Persona *pl)
{
printf("\n\n");
printf("lista: \n");
while (pl){
printf("%s\n", pl->nome);
pl = pl->p_next;
}
printf("\n\n");
}

tuccio`
02-07-2011, 15:12
scanf("%d",dato_e);

dovrebbe essere

scanf("%d",&dato_e);

devil_prince
02-07-2011, 15:15
scanf("%d",dato_e);

dovrebbe essere

scanf("%d",&dato_e);


Si hai ragione :doh:

devil_prince
02-07-2011, 16:01
Ora ho creato anche una funzione per l'inserimento in coda, però appena inserisco il secondo nome il primo assume valori random sia se uso la funzione in testa sia quella in cosa, perde il valore precedentemente meorizzato, come faccio per conervarlo?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char nome[20];
short eta;} Info;
typedef struct persona{
Info info;
struct persona *p_next;} Persona;


void insl_testa(Info , Persona **);
void insl_coda (Info , Persona **);
void insl_nodo(Info , Persona **);
void print_lista(Persona *);
void main ()
{
int op, menu=100;
Persona *head, *punt;
Info dato;
head=NULL;//creiamo la lista

while (menu<=100)
{
puts("\n\n\n=======================");
puts("GESTIONE DI UNA LISTA");
puts("=======================\n\n");
puts("Selezionare l'operazione:\n");
puts("1=Visualizzare la lista");
puts("2=Inserire un elemento");
puts("3=eliminare un elemento");
scanf("%d",&op);

switch (op)
{
case 1: print_lista(head); break;

case 2 :if (head==NULL){
printf("Inserie il nuovo nome: ");scanf("%s",dato.nome);
printf("Inserie l'eta': ");scanf("%d",&dato.eta);
insl_testa(dato,&head);break;}
else{
printf("Inserie il nuovo nome: ");scanf("%s",dato.nome);
printf("Inserie l'eta': ");scanf("%d",&dato.eta);
if(strcmp(punt->info.nome,dato.nome)<0){
insl_testa(dato,&head);}
else{
insl_coda(dato,&head);}

}; break;
}
}
}
void insl_testa (Info dato, Persona **p_head)
{
Persona *ptr;
ptr=calloc(1,sizeof(Persona));//allochiamo memoria per il nuovo nodo
//assegna alla nuova memoria allocata il nuovo nodo
ptr->info=dato;
ptr->p_next=*p_head;//il puntatore successivo assume il valore di quello di testa (cioè il punt di testa non è più di testa)
*p_head=ptr;//aggiorniamo head al nuovo nodo, il nuovo nodo diventa puntato dal puntatore di testa
}
/*void insl_nodo(char dato_n[20], short dato_e, struct persona **p_punt)
{
struct persona *ptr;
ptr=calloc(1,sizeof(struct persona));
strcpy(ptr->nome,dato_n);
ptr->eta=dato_e;
ptr->p_next=(*p_punt)->p_next;
(*p_punt)->p_next=ptr;
*p_punt=ptr;
}*/
void insl_coda (Info dato, Persona **p_head)
{
Persona *ptr;
ptr=calloc(1,sizeof(Persona));
ptr->info=dato;
ptr->p_next=NULL;
(*p_head)->p_next=ptr;
}
void print_lista(Persona *pl)
{
printf("\n\n");
printf("lista: \n");
while (pl){
printf("%s\t%d\n", pl->info.nome,pl->info.eta);
pl = pl->p_next;
}
printf("\n\n");
}