Pour ma première question ici, Je voudrais parler de la lecture de fichiers binaires en C++; Je recode une bibliothèque de balises ID3.C++, comportement bizarre lors de la lecture binaire ifstream
J'analyse l'en-tête qui est un fichier binaire, les premiers 10bytes sont les suivantes:
ID3 = 3 bytes = constant identifier
0xXXXX = 2 bytes = version (MSB: major version, LSB: minor. eg: 0x0301 = v3.1)
0xXX = 1 byte = some flags
4*0xXX = 4 bytes = size
ici est le morceau de code pour traiter que:
char id[4];
uint16_t version;
uint8_t flags;
uint32_t size;
std::ifstream _stream;
_stream = std::ifstream(_filename, std::fstream::binary);
_stream.read(id, 3);
id[3] = 0;
// process id
_stream.read((char *)&version, 2);
// process version
_stream.read((char *)&flags, 1);
// process flags
_stream.read((char*)&size, 4);
// process flags
_stream.close();
tout fonctionne bien sauf pour la version. disons que c'est v3.0 (0x0300), la valeur définie dans la version est 0x03, je comprendrais ce comportement en mode texte car il considérerait 0x00 comme la fin de la chaîne, mais ici je lis en binaire. Et utilisez des formats numériques.
Autre chose étrange, si je le processus en 2 fois, je peux le faire fonctionner, par exemple:
uint16_t version = 0;
char buff;
_stream.read(&buff, 1);
version = (buff << 8);
_stream.read(&buff, 1);
version |= buff;
Dans ce cas, la valeur de la version est 0x0300.
Avez-vous une idée de la raison pour laquelle la première méthode ne fonctionne pas correctement? Est-ce que je fais quelque chose de mal?
Quoi qu'il en soit, merci pour votre aide,
Cheers!
Voici quelques aliments google pour vous: « little endian » et « grand endian ". –
Vous devez d'abord définir précisément votre format de fichier (peut-être en notation EBNF) –
En passant, si vous cherchez un code indépendant de la plate-forme, il n'y a aucune garantie qu'un octet est 8 bits (ces mêmes plates-formes où cas probablement aussi ne supporterait pas non plus les types entiers à largeur fixe) – AndyG