PDA

Visualizza la versione completa : [C++] Problema fwrite()


GliderKite
07-06-2010, 19:04
Perchè usando la fwrite(), per esempio del numero 480:




FILE* pFile;
short int x = 480;
short int* px = &x;

fwrite(px, sizeof(short int), 1, pFile);


Leggendo poi il file mi appare scritto (in esadecimale): E0 01, invece che 01 E0? (480 = 0x1E0).

Come posso fare in modo che nel file scritto appaiano scritti nell'ordine esatto 01 E0?


Grazie.

oregon
07-06-2010, 19:10
E' quello l'ordine esatto.

MItaly
07-06-2010, 19:12
http://en.wikipedia.org/wiki/Endianness
Nello specifico, le macchine x86 sono little-endian.

GliderKite
07-06-2010, 19:18
Originariamente inviato da oregon
E' quello l'ordine esatto.

Perchè?


Vado più in specifico allora.

Dato un numero minore di 0xFFFFFFFF, devo scrivere su file 4 byte che lo rappresentano, quindi, sempre per fare un esempio, dato il numero 480, su file deve essere necessariamente scritto:

00 00 01 E0

Come fare?

oregon
07-06-2010, 19:26
I 4 byte che lo rappresentano sono

00 00 E0 01

e lo rileggerai correttamente.


Dai un'occhiata al link di MItaly e poi cerca anche informazioni sulle funzioni

htonl

e

ntohl

MItaly
07-06-2010, 21:24
Per fare quello che chiedi in maniera portabile devi in primo luogo determinare se l'architettura è big-endian o little-endian; di solito si lo si fa "manualmente" a compile-time definendo macro adeguate, ma si può fare anche in automatico a runtime.


class EndianConversion
{
private:
bool littleEndian;

public:
inline bool IsLittleEndian() { return littleEndian; };

EndianConversion()
{
unsigned int test=0xff;
littleEndian=*((unsigned char *)(&test));
}

// Inverte l'ordine dei byte di un valore
// Nota: ovviamente T deve essere POD
template<typename T>
T InvertBytes(T In)
{
T out=In;
unsigned char * bytePtr=(unsigned char *)&Out;
unsigned char temp;
for(size_t pos=0;pos<sizeof(In)/2;pos++)
{
temp=bytePtr[pos];
bytePtr[pos]=bytePtr[sizeof(In)-pos];
bytePtr[sizeof(In)-pos]=temp;
}
return Out;
}

template<typename T>
T ToBigEndian(T In)
{
return IsLittleEndian()?InvertBytes(In):In;
}

template<typename T>
T ToLittleEndian(T In)
{
return IsLittleEndian()?In:InvertBytes(In);
}
};

Scritta al volo, non garantisco sul funzionamento effettivo... :zizi:
---EDIT---
Uff, ma non esistono i costruttori statici in C++... mi tocca cambiarla...
---RIEDIT---
Ok, ora sono tutti membri d'istanza; naturalmente una classe del genere va considerata un singleton, non ha alcun senso crearne più di una istanza.

GliderKite
08-06-2010, 11:47
Grazie a tutti e due :)

Link interessante MItaly, alla fine comunque ho optato per un codice meno "elegante" ma più intuitivo e breve che permette di fare in modo da scrivere 4 byte nell'ordine desiderato grazie alla tmpfile().

MItaly
08-06-2010, 15:09
Cosa c'entra la tmpfile adesso? :master:

linoma
08-06-2010, 15:19
Scrivilo cm stringa hex, cs nn hai neanche bisogno di un editor esadecimale.

GliderKite
09-06-2010, 10:23
Originariamente inviato da MItaly
Cosa c'entra la tmpfile adesso? :master:


Se ricordi lo scopo di tutto era quello di scrivere 4 byte (nell'ordine "corretto") in un file aperto in modalita binaria. Se invece di scriverlo direttamente nel file di destinazione, utilizzo la tmpfile(), diventa poi facile ordinare i byte come si desidera.

Loading