PDA

Visualizza la versione completa : [C] Liste e Array di stringhe


goatboy
08-06-2012, 09:59
Salve a tutti. Sto svolgendo una prova d'esame come esercitazione. Devo creare una funzione che crei un array di stringhe contenente tutte le razze presenti in un canile (dato che la razza non è una chiave, ci saranno più cani per razza, ma nell'array deve esserci una sola occorrenza per razza).

Ho scritto le due funzioni di crea_elenco_razze e stampa_razze. Ma quando vado per compilare e premo 2 ("Ricerca e Stampa Razze") non fa niente e passa subito al system("PAUSE").
Sicuramente il problema è nella funzione di creazione dell'elenco, ma non mi da errori e non capisco dove sia l'errore.

Questa è la funzione di creazione dell'elenco razze:


int crea_elenco_razze(TList list, char elenco[][MAXCHAR]){
int i=0, j;

if(list==NULL){
printf("La lista e' vuota.\n");
}

while(list!=NULL){
for(j=0; j<i; j++){
if(!strcmp(elenco[i], list->info.satellite.razza)){
strcpy(elenco[i], list->info.satellite.razza);
i++;
}
}
list=list->link;
}

return i;
}

In sostanza ho provato , con il ciclo for, a fare un controllo per vedere se la razza che stavo visualizzando non fosse già inserita nell'elenco, ma credo di aver combinato un macello. Di mattina do il meglio di me :madai!?:

Questa è la funzione di stampa che credo (spero) vada bene:


void stampa_razze(char elenco[][MAXCHAR], int riemp){
int i;
for(i=0; i<riemp; i++){
printf("%s\n", elenco[i]);
}
}


Qualche suggerimento?

goatboy
08-06-2012, 10:26
Ho modificato così la funzione di creazione dell'elenco, ora mi stampa le razze ma non tiene conto delle occorrenze, quindi se ci sono due cani della stessa razza, la stampa due volte. Non ho idea di come poter fare un controllo per verificare che la razza non sia stata già inserita..



int crea_elenco_razze(TList list, char elenco[][MAXCHAR]){
int i=0, j;

// Lista vuota
if(list==NULL){
printf("La lista e' vuota.\n");
}

// La prima razza sicuramente va inserita
strcpy(elenco[i], list->info.satellite.razza);
i++;
list=list->link;

while(list!=NULL){
if(strcmp(elenco[i], list->info.satellite.razza)!=0){
strcpy(elenco[i], list->info.satellite.razza);
i++;
}
list=list->link;
}

return i;
}

Mond0
08-06-2012, 11:28
era meglio il primo codice. Riguarda questo pezzo:


for(j=0; j<i; j++)
{
...
}

i vale 0 inizialmente, quindi non entrerà mai...

goatboy
08-06-2012, 12:27
Originariamente inviato da Mond0
era meglio il primo codice. Riguarda questo pezzo:


for(j=0; j<i; j++)
{
...
}

i vale 0 inizialmente, quindi non entrerà mai...

Ok, sono ritornato al primo codice. Ho impostato i ad 1 inizialmente e poi prima del return la diminuisco di uno.
Ma in ogni caso quando avvio la funzione non mi fa niente. Non crasha e non da problemi.

Mond0
08-06-2012, 12:48
i passi che devi fare sono:
- il primo elemento della lista lo copi subito;
- entri nel while dove scorrerai i vari elementi della lista restanti;
- dentro il while, altro ciclo per confrontare l'elemento della lista preso in esame in quella istanza con gli elementi già copiati nel vettore. Quindi ad esempio al primo "giro" nel while il for sarà:


for(j=0;j<1;j++) //in modo da controllare solo il primo elemento

poi al secondo giro dovrà essere (in caso hai copiato sul vettore):


for(j=0;j<2;j++) //in modo da controllare i primi due elementi


N.B. ovviamente ci vuole una variabile che si incrementa opportunamente ogni volta che si rientra nel while assumendo i valori 1,2,ecc..
- se l'elemento della lista considerato è diverso da tutti gli elementi già copiati nel vettore allora lo copi;

goatboy
08-06-2012, 13:15
Grazie per l'aiuto. Ho provato a scrivere così, ma va in crash:



int crea_elenco_razze(TList list, char elenco[][MAXCHAR]){
int i=0, j, k=1;

// Caso banale: lista vuota
if(list==NULL){
printf("La lista e' vuota.\n");
}

// Copio il primo elemento della lista
strcpy(elenco[i], list->info.satellite.razza);
i++;
list=list->link;

while(list!=NULL){
for(j=0; j<k; j++){
if(!strcmp(elenco[j], list->info.satellite.razza)){
strcpy(elenco[i], list->info.satellite.razza);
i++;
k++;
}
}
list=list->link;
}

return i;
}

Mond0
08-06-2012, 13:54
for(j=0; j<k; j++){
if(!strcmp(elenco[j], list->info.satellite.razza)){
strcpy(elenco[i], list->info.satellite.razza);
i++;
k++;
}
}

in questo pezzo: preso un elemento della lista tu lo confronti con il primo in elenco, se è diverso lo copi. Ma devi controllare tutti gli elementi già in elenco e solo dopo (in caso non ci siano razze già presenti nel vettore) copiare...

goatboy
08-06-2012, 13:56
Originariamente inviato da Mond0


for(j=0; j<k; j++){
if(!strcmp(elenco[j], list->info.satellite.razza)){
strcpy(elenco[i], list->info.satellite.razza);
i++;
k++;
}
}

in questo pezzo: preso un elemento della lista tu lo confronti con il primo in elenco, se è diverso lo copi. Ma devi controllare tutti gli elementi già in elenco e solo dopo (in caso non ci siano razze già presenti nel vettore) copiare...

Non so proprio come poterlo fare.. :confused:
Non mi viene in mente niente, sarà che sono stanco.. Qualche suggerimento?

Mond0
08-06-2012, 14:08
allora, in pseudo-codice:


for(j=0;j<(numero elementi già copiati nel vettore);j++){
if(strcmp(...)){
//ci metti qlc per memorizzare che un elemento in elenco è uguale all'elemento della lista;
break;
}
}
if(elemento della lista in esame non è presente in elenco)
{
strcpy(...);
//è aumentato il numero di elementi copiati nel vettore, quindi aggiorni qlc :P;
}
list = list->link;



tutto ovviamente dentro il while...

goatboy
11-06-2012, 09:36
Ho scritto così, ma non ho ancora provato a compilare..



while(list!=NULL){
for(j=0; j<i; j++){
if(strcmp(elenco[i], list->info.satellite.razza)==0){
flag=1;
break;
}else
flag=0;
}
if(flag==0){
strcpy(elenco[i], list->info.satellite.razza);
i++;
}
list=list->link;
}

Loading