Newsgroup: it.comp.programmare.win32
Titolo: come leggo una WORD da un file?

Ciao,
vorrei leggere 2 byte nello stesso ordine in cui sono scritti in un file,
Con il codice...
CFile file;
file.Open( "aa.txt",CFile::modeRead|CFile::typeBinary);
WORD prova=NULL;
file.Read(&prova,sizeof(prova));
...alla fine mi ritrovo con la mia WORD che ha i valori esattamente 
invertiti,
cioč il primo byte letto come byte meno significativo nella WORD e 
viceversa,
č normale questo?
P.S. sono ovviamente nuovo del C/C++
Grazie:

 
Non è una questione di C/C++, ma di processore.
Ti dicono nulla i nomi big-endian e little-endian?
:-)
la tecnologia Intel è little-endian, quindi se nel file è scritto
12 34 , leggendo 2 byte come word ottieni 0x3412
LP

 12 34 , leggendo 2 byte come word ottieni 0x3412
Visto che evidentemente non lo sapeva, forse vale la pena di fare la 
precisazione che è solo un problema di rappresentazione in memoria. E che 
quindi se poi riscrive il tutto su file non deve stare a girarsi i byte.
-- 
Raffaele Rialdi
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
http://italy.mvps.org
 UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
 Weblog: 
http://blogs.ugidotnet.org/raffaele

Grazie a tutti e due,
devo leggere un valore codificato in bit (16) in mezzo ad uno stream
che registro preventivamente su file, ho pensato allora di usare una
union in questo modo...
 union TEST
 {
  WORD risultato;
  unsigned char scambio[2];
 }Test;
 for(int a=1;a>-1;a--)
//**leggo i 2 bytes immagazzinando il primo in fondo all'array
  file.Read(&Test.scambio[a],1);
..a questo punto in Test.risultato ho il valore che cerco,
non conosco bene la union, ma se sto attento a non modificare i
valori nella array scambio dovrei essere a posto(?),
oppure c'è un modo migliore?
Grazie di nuovo.
Carlo



In linea di principio va benino.
<piccola spiegazione, una soluzione alla fine>
Esisterebbero le funzioni ntohs htons a questo scopo (scambiare i byte 
in una word) che sono state create per comodità in quanto si è deciso 
(ti lascio il divertimento di una piccola ricerca, se se interessato) di 
parlare con numeri big-endian sulla rete. Dal momento che esistono 
processori come Intel che sono Little-endian, sono fornite queste due 
funzioni che in caso di sistemi big-endian non alterano il valore, in 
caso di sistemi little-endian fanno la relativa conversione scambiando i 
bytes.
Se ti stai chiedendo perché due funzioni e non una sola, ti rispondo con 
due informazioni:
1) htons e ntohs stanno per Host TO Network Short e Network TO Host 
Short (esistono anche le versioni per i long)
2) esistono (sono rari per fortuna, ma esistono) i sistemi middle-endian 
che rappresentano valori come 0x11223344 in memoria come (in ordine di 
indirizzo) 33 44 11 22 (i little-endian lo rappresenterebbe come 44 33 
22 11, i big endian come 11 22 33 44)
</piccola spiegazione>
Una soluzione quindi potrebbe essere di leggere a word, invocare un 
*ntohs* per passare da big-endian all'endianness del tuo processore (non 
esiste solo Intel) e prima di salvare i dati invochi *htons*, poi scrivi 
la word.
Il vantaggio (a parte il fatto di non lavorare su union, ma su strutture 
di base) è che se tu passassi su un processore big-endian come PowerPC 
(penso anche ARM, ma non sono sicuro), nella lettura hai la funzione che 
legge sempre i bytes nell'ordine che vuoi tu, quindi la funzione lavora 
correttamente senza ulteriori modifiche.
LP
PS: la union ti permette di leggere una zona dati con diverse chiavi di 
lettura (nel tuo caso una word o una array di caratteri senza segno).
Modificare un elemento della union modifica immediatamente anche il 
resto. Si può facilmente implementare con una operazione di casting di 
puntatori (che sono assai meno eleganti)
LP

remove wrote:
[...]
Oltre all'ottima descrizione di Luca, se ti interessa avere la portabilità 
continua ad usare le funzioni da lui indicate.
Io avendo bisogno delle massime prestazioni, e usandole solo su x86, mi ero 
scritto queste:
void ENDIAN(LONG *pa)    // 32 bit
{
 LONG b = *pa;
 _asm
 {
 push eax
 mov eax,b
 xchg ah,al
 rol eax,16
 xchg ah,al
 mov b,eax
 pop eax
 }
 *pa = b;
}
void ENDIAN(SHORT *pa)    // 16 bit
{
 SHORT b = *pa;
 _asm
 {
 push ax
 mov ax,b
 xchg ah,al
 mov b,ax
 pop ax
 }
 *pa = b;
