Newsgroup: it.comp.lang.c
Titolo: ricavare una struct da un file...

Salve a tutti programmatori di c...
Avendo un file binario con un header del tipo
"abcdXYZ\0\1\2\3\4"
volevo ricavare delle informazioni dalle singole componenti dei files (in
questo caso una stringa da 4 caratteri "abcd", una di 3 "XYZ" uno short int
"0x0100" un char "0x02" uno short int "0x0403", infatti i numeri li vorrei
in formato Little Endian) per poi poterle
rimaneggiarle/stamparle/risalvarle, nei loro singoli componenti.
Per fare cio' avevo pensato di creare una struttura del tipo:
struct prova
{
 char a[4];
 char b[3];
 unsigned short int c;
 unsigned char d;
 unsigned short int e;
};
e poi eseguire un memcpy da un buffer di caratteri che contiene il file.
A questo punto sorgono due problemi:
1- le stringhe dovrebbero essere NULL terminated e quindi fa a farsi
benedire il memcpy
2- inoltre ho notato che la sizeof della struttura e' piu' grande della
somma delle sizeof dei componenti.
per concludere...
Qualcuno saprebbe crearmi una funzione del tipo:
void funz(FILE *fp, struct prova *risultato)
che mi salvi i dati dal file gia' aperto con fp nella struttura puntata da
risultato (possibilmente con gli short int in little endian)
Altrimenti ci sono delle alternative valide alle struct in questo caso?
Spero che questa domanda non sia gia' stata posta altresi' pregherei di
fornirmi almeno la data della risposta.
Saluti e ringraziamenti sentiti per l'attenzione...
--
Golden...@gmx.net

 somma delle sizeof dei componenti.
Perche` una struttura non e` necessariamente 'packed'.  Ci possono
essere degli spazi 'vuoti' dentro per fare il 'byte aligning'.
 
Ciao,
-- 
David N. Welton
   Consulting: 
http://www.dedasys.com/
Free Software: 
http://people.debian.org/~davidw/
   Apache Tcl: 
http://tcl.apache.org/
     Personal: 
http://www.efn.org/~davidw/

 essere degli spazi 'vuoti' dentro per fare il 'byte aligning'.
Grazie mille per la risposta!
se io sovrascrivo la struct con un carattere '\0' (per avere subito le Null
terminated strings) sovrascrivo delle informazioni importanti oppure e' una
cosa fattibile senza alcun pericolo? In che misura viene effettuato il byte
aligning in una struttura non packed?
Saluti
--
Golden...@gmx.net

 essere degli spazi 'vuoti' dentro per fare il 'byte aligning'.
Io non sono d'accordo.
Esiste la direttiva #pragma pack (packLevel) che puoi inserire a tuo
piacimento.
Byes
FusionFai

"FusionFai" <fusio...@NOSPAMflashnet.it> writes:



E` ANSI C?
Dal manuale di GCC:
        The ANSI standard specifies that the effect of the `#pragma'
        directive is implementation-defined.
Io non mi fiderei.


E poi rifare la stessa cosa quando leggi.
Una delle caratteristiche che distingue il C dagli altri linguaggi e'
l'efficienza. Cio' che hai scritto e' un insulto al linguaggio.
ciao, acc.   
a...@libero.it

Io non mi fiderei.
Io non fiderei di GCC...
ciao, acc.   
a...@libero.it

acc <a...@libero.ita> writes:


E allora - una soluzione, portabile, e conformante agli standard?
Molto dipende da quello che vuole fare la persona in questione, ma sta
di fatto che senza fare il marshalling, non puoi pretendere di fare
una cosa minimamente portabile.  Puo` essere che questo non gli
importa.


 Io non fiderei di GCC...
Perche` non dici qualcosa di concreto invece di lanciare flame-bait
qua e la`?
*PLONK*


Se non credete a me, leggete qua:
http://www.eskimo.com/~scs/cclass/int/sx3b.html
 
o qua:
http://sources.redhat.com/autobook/autobook/autobook_115.html
o qua per altre discussioni simili:
http://www.advogato.org/article/97.html
e un altro, tanto per dirlo ancora:
http://www-ccs.ucsd.edu/c/portable.html


fornirmi almeno la data della risposta.
E' una domanda abbastanza ricorrente... comunque la
risposta base e' (se ti interessa scrivere codice
anche minimamente portabile) non usare mai lettura/
scrittura di intere struct. Quell'approccio e' accettabile
solo per file che vengono letti e scritti solo da una
versione specifica del tuo programma e che non prevedi
dovranno mai essere usati da altri (es. tuoi file temporanei).
E' secondo me sconsigliabile salvare/caricare intere struct
anche per archiviare dati in modo permanente in un tuo
formato (se ad esempio tu scrivessi un word processor)
visto che potresti avere problemi anche con un semplice
cambio di compilatore e comunque diventerebbe molto piu'
complicato gestire il versioning.
Se hai problemi di prestazioni la cosa puo' essere
risolta con tecniche di buffering. Leggere/scrivere
l'intera struttura con fread/fwrite comunque non sarebbe
in genere l'approccio piu' performante.
Io ho trovato comodo usare una tecnica simile a quella
che ti ho mostrato con in piu' due piccole varianti:
  - la sorgente dei byte non e' fread ma un'altra
    funzione (scritta da me)
  - le funzioni di lettura tornano 1 (true) se la
    lettura e' andata bene e 0 altrimenti
es.
  int read_short(ByteSource *src,short *s)
  {
    unsigned char buf[2];
    read_buf(src,buf,2); *s=buf[0]+(buf[1]<<8);
    return src->ok;
  }
in questo modo il codice di lettura/scrittura rimane
molto semplice anche gestendo correttamente gli errori
puo' diventare abbastanza performante con poco sforzo
ed inoltre si generalizza per altre destinazioni che
non siano file (puoi usare le stesse funzioni per
salvare su disco i tuoi dati o per inviarli via
rete... oppure per aggiungere una compressione dati).
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

l'efficienza. Cio' che hai scritto e' un insulto al linguaggio.
Usare fread/fwrite di strutture non e' un modo per scrivere
codice efficiente. La differenza la fanno il numero di
chiamate di I/O e quindi per leggere in maniera efficiente
e' necessario usare tecniche di buffering e al limite di
I/O parallelo e questo puo' essere fatto anche leggendo
campo-a-campo e senza perdere quindi di flessibilita' e
portabilita'.




Non esiste su tutti i compilatori. Ad esempio su
alcune architetture e' fisicamente impossibile per
la CPU accedere in memoria ad un intero 32 bit che
non inizi ad un indirizzo multiplo di 4 tranne che
facendone una lettura byte-a-byte.
Inoltre non tutti i compilatori prevedono la
possibilita' di "compattare" le strutture anche
dove l'architettura lo permette.
Esistono anche mille altri motivi per non usare
fread/fwrite di intere strutture tranne che per
file *temporanei* usati dal programma (portabilita',
facilita' gestione versioning, riusabilita' al
variare della destinazione/sorgente, possibilita'
di piping, conversioni charset, prestazioni).


qua e la`?
Non era un flame, era qualcosa di concreto.
Nessuno che voglia scrivere codice efficiente usa il metodo da te
proposto.
ciao, acc.   
a...@libero.it

portabilita'.
D'accordo, pero' anche ogni chiamata di troppo alla fread/fwrite fa'
calare l'efficienza del codice, meglio evitarla. Non mi sembra cosi'
difficile...
ciao, acc.   
a...@libero.it

 difficile...
E` meglio codice corretto che codice veloce.  Codice veloce e
scorretto ha solo l'effetto di fare errori piu` velocemente.


scorretto ha solo l'effetto di fare errori piu` velocemente.
Non e' il codice che e' scorretto, casomai, in questo caso, e' il
compilatore o forse il programmatore, che vuole evitare a tutti i
costi di dare un'occhiatina alle specifiche dello stesso, a costo di
leggere e scrivere bit per bit...
Scherzi a parte, non ho mai visto un sw serio che utilizzi tale
metodo, e se di sw serio si tratta a questo punto preferisco rimanere
nel mio mondo 'soft'...
ciao, acc.   
a...@libero.it

 mio mondo 'soft'...
-- 


girera` altrove.
Non mi riferivo solo al mondo wintel, BTW sono anche molto scettico
riguardo alla portabilita', spesso e' piu' comodo ignorarla ed
eventualmente fare le modifiche in seguito; beninteso ad esclusione
dei casi di assoluta necessita'.
Per me ognuno e' libero di fare cio' che vuole, non mi permetto di
criticare chi scrive codice portatile e non mi va' di essere criticato
se faccio il contrario.
ciao, acc.   
a...@libero.it