[C] File binari e strutture dati dinamiche
Salve ragazzi, avrei una domanda su quale sia il miglior metodo per leggere da file binario e memorizzare i dati letti in una struttura dinamica. Io faccio così, ma mi sembra un pò ridondante:
Insomma quello che intendo dire è che non mi piace tanto aver dovuto definire due tipi praticamente uguali.
Si può ottimizzare in qualche modo la cosa? O va bene così?
Grazie mille per l'attenzione
typedef struct { int id; char stringa[MAXCHARS]; } t_coppie; typedef struct node *link; struct node { int id; char *stringa; link next; };
link storeList(FILE *fp, link head) { t_coppie coppie; link p; while (fread(&coppie, sizeof(coppie), 1, fp)>0) { p=malloc(sizeof(*p)); p->id=coppie.id; p->stringa=malloc(1+strlen(coppie.stringa)); strcpy(p->stringa, coppie.stringa); p->next=NULL; head=insertTail(head, p); } return head; }
Insomma quello che intendo dire è che non mi piace tanto aver dovuto definire due tipi praticamente uguali.
Si può ottimizzare in qualche modo la cosa? O va bene così?
Grazie mille per l'attenzione

Risposte
A proposito, un'altra cosa su cui sono perplesso è il fatto di aver dovuto dichiarare il campo "stringa" come array statico di char in un typedef e come puntatore a char nell'altro.
Il motivo è che, nella creazione del file, ho usato stringa[MAXCHARS] perchè altrimenti invece di salvare la stringa, la fwrite salvava il puntatore e naturalmente esso restava valido finchè usavo la free o finchè non chiudevo il programma. Dopo di che alla riapertura del programma chiaramente quel puntatore andava a puntare qualcosa che non aveva niente a che fare con le stringhe a cui era stato inizialmente assegnato. Quindi mi chiedo, se il codice che ho scritto sopra va migliorato, oppure se la cosa migliore è restare sul semplice e lasciare le cose come stanno visto che funziona?
Il motivo è che, nella creazione del file, ho usato stringa[MAXCHARS] perchè altrimenti invece di salvare la stringa, la fwrite salvava il puntatore e naturalmente esso restava valido finchè usavo la free o finchè non chiudevo il programma. Dopo di che alla riapertura del programma chiaramente quel puntatore andava a puntare qualcosa che non aveva niente a che fare con le stringhe a cui era stato inizialmente assegnato. Quindi mi chiedo, se il codice che ho scritto sopra va migliorato, oppure se la cosa migliore è restare sul semplice e lasciare le cose come stanno visto che funziona?
Credo che sia difficile da una porzione di programma capire se il codice sia buono o meno, ci sono mille ragioni per definire due tipi simili come ce ne sono mille per non farlo... a quanto si vede dal ciclo di lettura il puntatore p viene utilizzato da una funzione.
E' chiaro che tutti gli indirizzi di memoria del programma esistono solo ed esclusivamente nel ciclo di vita del programma stesso, quindi è normale che quando si chiude il programma gli indirizzi siano assegnati ad altre istanze. Quando si riapre il programma viene eseguita una nuova ri-allocazione della memoria tutta.
comunque una soluzione per definire un struttura più compatta potrebbe essere:
in questo modo la struct t_coppie contiene un membro node, ma dato che non è chiaro cosa faccia il programma se questo sia un buon modo.
saluti
E' chiaro che tutti gli indirizzi di memoria del programma esistono solo ed esclusivamente nel ciclo di vita del programma stesso, quindi è normale che quando si chiude il programma gli indirizzi siano assegnati ad altre istanze. Quando si riapre il programma viene eseguita una nuova ri-allocazione della memoria tutta.
comunque una soluzione per definire un struttura più compatta potrebbe essere:
typedef struct node *link; struct node { int id; char *stringa; link next; }; typedef struct { link p; char stringa[MAXCHARS]; } t_coppie;
in questo modo la struct t_coppie contiene un membro node, ma dato che non è chiaro cosa faccia il programma se questo sia un buon modo.
saluti
Il migliore metodo per leggere da file binario e inserire i valori in un qualche tipo di struttura dati è ovviamente quello di memorizzare la struttura dati così com'è in memoria. Questo non è però possibile farlo quando si usano puntatori ed è quindi necessario rimediare in qualche modo. Le soluzione possibili sono principalmente le seguenti:
1. Modificare la struttura dati in memoria in modo da usare indici al posto di puntatori.
2. Modificare i "puntatori" durante la scrittura su file in modo che contengano la posizione della corrispondente struttura nel file. Dopo aver letto il file intero in memoria è però poi necessario iterare su tutta la struttura per correggere tutti i puntatori in modo che contengano il corretto indirizzo di memoria (normalmente si tratta semplicemente di aggiungere a tutti i puntatori l'indirizzo al blocco allocato per inserire la struttura).
3. Fare come hai fatto.
Di tutte le possibili soluzioni la prima è la più desiderabile quando possibile. La seconda potrebbe apparire complicata ma è un metodo molto flessibile e permette di caricare praticamente qualsiasi tipo di struttura senza problemi (fanno ovviamente eccezioni strutture che contengono riferimenti a file o altre cose simili..).
1. Modificare la struttura dati in memoria in modo da usare indici al posto di puntatori.
2. Modificare i "puntatori" durante la scrittura su file in modo che contengano la posizione della corrispondente struttura nel file. Dopo aver letto il file intero in memoria è però poi necessario iterare su tutta la struttura per correggere tutti i puntatori in modo che contengano il corretto indirizzo di memoria (normalmente si tratta semplicemente di aggiungere a tutti i puntatori l'indirizzo al blocco allocato per inserire la struttura).
3. Fare come hai fatto.
Di tutte le possibili soluzioni la prima è la più desiderabile quando possibile. La seconda potrebbe apparire complicata ma è un metodo molto flessibile e permette di caricare praticamente qualsiasi tipo di struttura senza problemi (fanno ovviamente eccezioni strutture che contengono riferimenti a file o altre cose simili..).
Ok vi ringrazio tantissimo per tutto l'aiuto che mi avete dato 
Io ho fatto l'esame il 30 Agosto, oggi sono usciti i voti e ho preso 30.
L'esame si basava su una struttura "albero di liste".
Ringrazio tutti quelli che mi hanno aiutato ma evitando di fare la lista perchè potrei dimenticare qualcuno

Io ho fatto l'esame il 30 Agosto, oggi sono usciti i voti e ho preso 30.
L'esame si basava su una struttura "albero di liste".
Ringrazio tutti quelli che mi hanno aiutato ma evitando di fare la lista perchè potrei dimenticare qualcuno
