matt_dev

Programmazione [Linguaggio C] - Liste impazzite

Recommended Posts

(Ri)salve per un mio ennesimo problema con questo linguaggio :peo:

 

Ho da consegnare un esercizio che recita:

Un file di testo (stringhe.txt) contiene un numero indefinito di stringhe (di massimo 30 caratteri) da memorizzare in una lista di stringhe. In questa lista, la stringa contenuta in ognuno dei suoi nodi deve essere rappresentata mediante il tipo char* e poi allocata dinamicamente della dimensione opportuna.
Si implementi in linguaggio C:
  • una struttura dati adatta a rispondere alle richieste di cui sopra
  • una funzione di inserimento in lista, che permetta di aggiungere le stringhe in maniera ordinata (alfabeticamente) man mano che queste sono lette da file
  • una funzione di memorizzazione su file della lista ordinata.

 

Allora, la struttura (presumo) è giusta, la memorizzazione su file non l'ho ancora fatta ma mi pare banale.. ma il secondo punto (ordinamento alfabetico soprattutto) non viene proprio.. c'è qualcosa che non va nella memorizzazione. Per adesso infatti, il programma (incompleto) in cui è implementata la lista, la funzione per acquisire i dati e (per debug) la funzione che stampa a video i contenuti di ogni lista, è il seguente:

#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_C 30+1typedef struct stringhe str;struct stringhe{    char *s;    str* next;};str* leggiLista(FILE* fp);str* newNode();void alphabeticSort(str* head, str* y, char* v);void stampaListe(str* x);int main(int argc, char** argv) {    FILE *fp;    str* x;    if (argc != 2) {        printf("Errore su linea di comando.\n");        exit(-1);    }    if ((fp = fopen(argv[1], "r")) == NULL) {        printf("Errore apertura file.\n");        exit(-1);    } else {        x = leggiLista(fp);    }    stampaListe(x);    fclose(fp);    return 0;}str* newNode() {    str* x;    x = malloc(sizeof(str*));    x->next = NULL;    return x;}str* leggiLista(FILE* fp) {    str *y, *head;    char v[MAX_C];    head = NULL;    y = NULL;    while (fscanf(fp, "%s", v) != EOF) {        if (y == NULL) {            head = newNode();            head->s = malloc((strlen(v)+1)*sizeof(char*));            strcpy(head->s, v);            y = head;        } else {            alphabeticSort(head, y, v);        }    }    return head;}void alphabeticSort(str* head, str* y,char *v) {    str *t, *t2, *nn;    t = head;    t2 = NULL;    while (t != NULL) {        if (strcmp(t->s, v) > 0) {            nn = newNode();            nn->s = malloc((strlen(v)+1)*sizeof(char));            strcpy(nn->s, v);            if(t2 == NULL) {                nn->next = t;                head = nn;            } else {                t2->next = nn;                nn->next = t;            }            return;        } else {            t2 = t;            t = t->next;        }    }    y->next = newNode();    y->next->s = malloc((strlen(v)+1)*sizeof(char));    strcpy(y->next->s, v);    return;}void stampaListe(str* x) {    int count = 1;    str *p;    p = x;    printf("Lista di stringhe:\n");    while (p != NULL) {        printf("%d) %s\n", count++, p->s);        p = p->next;    }    printf("\n");    return;}

Il file "stringhe.txt" è semplicemente questo (ogni prodotto separato da un a capo):

acqua
vino
arance
mele
fusilli
cola
latte
pane_bianco
pane_integrale
passata_pomodoro
salmone_affumicato
mozzarella
zucchero
farina_00
sale
grana_padano

 

Se compilo, le stringhe stampate sono inesatte.. dovrebbe stamparmi la lista di tutte le stringhe ordinate alfabeticamente.. invece me ne stampa solo cinque di esse (precisamente acqua e le ultime 4 ordinate).

Dove sbaglio? Siamo in 3 che non riusciamo a capire il problema :ymmio:

 

Spero di esser stato chiaro, un grazie enorme in anticipo :T.T:

 

EDIT IMPORTANTE: se cambio il file , mettendo zucchero al secondo posto, lo riordina e stampa bene :eqw: che diavolo può significare?

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

La struttura è corretta (anche se forse avrei usato il nome più canonico Node o simili, piuttosto di str). Ci sono alcuni punti da far notare:

exit(-1);

Di solito si usano numeri non negativi come parametro per la funzione exit().

malloc(... * sizeof(char*));...malloc(sizeof(str*)); 

Qui state allocando memoria per char* e str* che sono puntatori (generalmente 4 byte su x86, 8 byte su x64). Dovete allocare la memoria per il preciso tipo (struttura o meno) invece:

malloc(... * sizeof(char));...malloc(sizeof(str));

Meglio evitare i return nelle funzioni void:

return;

A questo punto conviene usare delle flag o, in un codice particolarmente delicato e performante, l'istruzione goto.
 
Ecco una cosa che mi ha insospettito invece:

y = head;

Quindi l'head della vostra lista è sia head che y? Ha un senso avere y come alias? Se ne può fare tranquillamente a meno, infatti dopo usate t come variabile temporanea.

 

Il problema? Ha richiesto un po' di debug ma sta nel caso in cui aggiungete zucchero appunto. La lista fino a quel punto è esatta, poi arriva questo valore, che deve andare in fondo.

Però il programma aggiunge zucchero e la lista diventa:

---------    ------------| acqua |    | zucchero |---------    ------------|   ----|--->|   NULL   |---------    ------------ 

E tutti i valori precedentemente inseriti dopo acqua vengono persi. Riuscite a capire dove sta l'errore a questo punto? (Ho già evidenziato in qualche modo il problema nei consigli).

 

P.S.

Ricordati di deallocare tutti le strutture e i loro membri interni.

 

P.P.S.

Chiamare le variabili con un nome più adatto possibile al suo scopo è un'arte, cerca però di rendere la lettura del codice la più semplice possibile. ;)

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

@Scanetatore grazie di nuovo per la celere risposta, purtroppo sono passato ad altri esercizi e quello l'ho semi-abbandonato..

Quando ci ritornerò sopra, ti dirò se così riesco a risolverlo o meno. Grazie ancora!

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

@Scanetatore grazie di nuovo per la celere risposta, purtroppo sono passato ad altri esercizi e quello l'ho semi-abbandonato..

Quando ci ritornerò sopra, ti dirò se così riesco a risolverlo o meno. Grazie ancora!

Figurati, se posso dare una mano ben venga. ;) Anche se sono ancora in fase di largo studio su questo linguaggio. ^^

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Figurati, se posso dare una mano ben venga. ;) Anche se sono ancora in fase di largo studio su questo linguaggio. ^^

 

Anche io, e le cose si fanno sempre più difficili.. devo dare questo esame di Algoritmi e Programmazioen Avanzata (anche detto "strutture dati") e sto implodendo.

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Anche io, e le cose si fanno sempre più difficili.. devo dare questo esame di Algoritmi e Programmazioen Avanzata (anche detto "strutture dati") e sto implodendo.

Se ne vedono delle belle in queste tipologie di corsi. ;) Personalmente l'ho apprezzato davvero molto, forse anche per il professore che ho avuto.

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti
Ospite
Questa discussione è chiusa.