2013-03-28 2 views
2

Je lis des données binaires simples, sans pointeurs, en utilisant des classes C++ sans rembourrage avec le code suivant:La meilleure façon de lire les données binaires en C++ en utilisant des classes sans rembourrage

#include <fstream> 
#include <iostream> 

using namespace std; 

class Data { 
    public: 
    int a; 
    int b; 
    short int c; 
    double d; 
}__attribute__((packed)); 

int main() { 
    Data myData;  
    ifstream ifs("test.bin", ios::binary); 
    ifs.read((char *)&myData, sizeof(myData)); 
    ifs.close(); 
} 

J'utilise cette méthode parce que les données peut avoir plus de 20 formats différents et je veux écrire plus de 20 classes différentes pour couvrir tous les formats qui pourraient apparaître. J'ai aussi lu que d'autres options incluent l'utilisation de champs de bits, de directives pragma, et même les routines de sérialisation boost (je ne peux pas parce que je dois utiliser std). Ma question est: est-ce la meilleure façon de lire des données binaires simples en utilisant des classes sans rembourrage? Suggérez-vous une autre alternative? Je voudrais savoir quelle est la méthode la plus sûre et la plus largement utilisée.

+2

Il n'y a pratiquement pas d'autre moyen qui soit aussi simple et efficace. Du moins pas que je sache. Il suffit d'appeler 'Data'' struct' pour bien regarder. – Aneri

+2

Votre approche est bonne. Vous pouvez considérer ['#pragma pack (push, 0)'] (http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html) pour permettre à votre code d'être supporté par plus de compilateurs. Cependant, aucune approche n'est garantie pour être supportée par C++. –

+0

Drew, ça répond vraiment très bien à ma question, j'essaie de trouver quelque chose qui soit compilateur, multi-plateforme, sûr. Pragma_pack est-il plus sûr? Pourriez-vous nous en dire un peu plus à ce sujet? –

Répondre

1

Je l'ai utilisé ces macros pour permettre struct emballés de compiler sur gcc et VC:

#ifdef _MSC_VER 
    #define BEGIN_PACK __pragma(pack(push, 1)) 
    #define END_PACK __pragma(pack(pop)) 
#else 
    #define BEGIN_PACK 
    #define END_PACK __attribute__((packed)) 
#endif 

Alors vous les utiliser comme feriez ceci:

BEGIN_PACK 
struct Data { 
    int a; 
    int b; 
    short int c; 
    double d; 
} END_PACK; 

Mais oui, c'est habituellement comment c'est fait. Notez que ce sont des extensions non standard.

C++ 11 a défini des directives d'empaquetage, mais je ne sais pas si elles sont encore supportées par les compilateurs.

+0

Est-ce que "__attribute __ ((packed))" ne fonctionne qu'avec gcc? –

+1

Oui. clang le supporte aussi, puisqu'il est compatible avec gcc. Mais oui, c'est une extension gcc. – mfontanini

+0

Certains compilateurs ont des fichiers d'en-tête 'pshpackX.h' et' poppack.h', où 'N' est l'alignement d'octets désiré (1, 2, 4, 8, etc.), pour cacher les détails spécifiques au compilateur. –

2

Typiquement, on utiliserait un struct au lieu d'un class, mais oui, le même concept s'applique aux deux.

+0

Merci pour la réponse, mais êtes-vous sûr que l'utilisation d'une structure au lieu d'une classe est préférable? J'ai lu qu'en C++, il est recommandé d'utiliser des classes pour être cohérent. J'ai aussi lu que la principale différence entre une classe et une structure est qu'une classe est privée par défaut alors qu'une structure est publique par défaut. –

+2

@JaimeCervantes La convention courante que j'ai vue est quand vous avez tout le membre public variaible et aucun getters ou setters utilisés, un 'struct' est normalement utilisé au lieu d'un' class'. – andre

Questions connexes