2016-06-15 2 views
0

Je veux lire certains octets de mon fichier en tant que valeur entière. Par exemple, le fichier contient la valeur 0x000003BB qui est égale à 955.C++ Comment lire les octets comme endianness Integer indépendant?

je pouvais lire les données de cette façon:

ifstream input ("C:/Desktop/myFile", ios::binary); 
uint8_t buffer[4] = {0}; 
input.read((char*)buffer, sizeof(buffer)); 

Mais comment puis-je convertir le tampon tableau à la valeur correspondante int 955? Et si possible d'une manière indépendante de l'endianness, parce que ceci et quelques autres fichiers dans l'ordre de Big Endian Byte mais mon système sont sur Little Endian Byte Order. Merci :)

Répondre

1

Je ne suis pas sûr que ce soit la meilleure solution, mais cela fonctionne.

uint8_t buffer[4] = {0}; 
input.read((char*)buffer, sizeof(buffer)); 
unsigned int result = buffer[0]; 
result = (result << 8) | buffer[1]; 
result = (result << 8) | buffer[2]; 
result = (result << 8) | buffer[3]; 
+0

il n'a pas considéré le boutisme. Si j'imprime les données-var j'ai obtenu la valeur '3137536000 'qui est égale à '0xBB030000' mais je dois obtenir '0x000003BB ' – Opa114

+0

@ Opa114 effectivement, ce code * considère * endianness * dans le sens où il fonctionne sur une machine de toute endianness. Il y a simplement une erreur, et cela convertit * little * endian, plutôt que big endian qui est ce que vous vouliez. Changez les indices de tampon pour aller de 0 à 3, et ça marchera. – user2079303

+0

@ user2079303 merci pour l'indice! – Opa114

1

Il n'y a pas besoin d'utiliser un tableau de uint8_t, vous pouvez direcly lire dans un nombre entier de 4 octets:

uint32_t data; 
input.read((char*)&data, sizeof(data)); 

EDIT:

Ce code fonctionne sur mon compilateur VC++:

#include<stdint.h> 
#include<intrin.h> 
#include<iostream> 

int main() 
{ 
    uint32_t data; 
    data = 0xBB030000; 
    data = _byteswap_ulong(data); 

    std::cout << data; 
} 

Si vous utilisez GCC, vous devez remplacer _byteswap_ulong avec __builtin_bswap32. Si vous avez besoin de code indépendant, vous devez créer le vôtre (probablement en plus de ces intrinsèques du compilateur).

+0

cela fonctionne, mais il n'a pas considéré l'endianness. Si j'imprime les données-var j'ai obtenu la valeur '3137536000' qui est égal à '0xBB030000' mais j'ai besoin d'obtenir' 0x000003BB' – Opa114

+0

Cela peut aider: http://stackoverflow.com/a/105339/264325 – Ajay

+0

le même piège, Ajay. OP ne sait pas si le fichier est gros ou petit et ils veulent un code générique pour gérer les deux cas. Tout protocole de fichier qui ne spécifie pas endian est défectueux et devrait revenir au laboratoire pour une refonte, mais .... – user4581301

1

Si votre système d'exploitation prend en charge Windows ou est POSIX, vous pouvez utiliser ntohl:

int data; 
input >> data; 
data = ntohl(data); 
+2

Sous Windows, il faut créer un lien vers 'Ws2_32.lib'. – Ajay