2010-04-24 3 views
0

J'essaie de lire les données structurées cryptées à partir du fichier en utilisant fread(). une fois que j'obtiens les octets de structure déchiffrés, j'aimerais les remettre dans cette structure. Comment convertir une structure en octets pouvant être reconstruits à partir d'octets?struct to bytes

+2

chaîne est std :: string? Si non, qu'est-ce que c'est? –

+0

Dave, Ceci est source de confusion. vous dites que l'identificateur 'string' dans la structure est en fait un typedef d'un char *? C'est ce que Neil demande. – zumalifeguard

+0

Un problème est que le type de données LONG n'est pas bien défini ... sur un ordinateur, il peut être 32 bits, et sur un autre ordinateur, il peut être 64 bits. À moins que les données ne sortent jamais d'un seul ordinateur, il serait préférable d'utiliser int32_t ou un autre type avec une largeur de bit bien définie. –

Répondre

1

Le problème est que std::string ne contient pas les octets en question, il contient un pointeur aux octets que vous voulez réellement stocker. Vous devriez probablement enregistrer chaque chaîne comme une chaîne terminée par un caractère nul, puis enregistrer un fichier brut longtemps après cela dans le fichier.

Si vous recherchez une solution de sérialisation «pointer et cliquer» comme celle fournie par .NET, vous ne trouverez pas ce que vous cherchez en C++. Boost's serialization library peut être utile car il va sérialiser certains objets de bibliothèque standard pour vous, mais vous aurez besoin de votre propre implémentation pour une classe définie par l'utilisateur comme ça.

0

Pour le cas général, écrivez une fonction pour sérialiser manuellement tous les membres de la structure et une autre pour créer une structure à partir d'un flux d'octets en désérialisant tous les membres dans l'ordre. Vous pourriez utiliser des scripts pour que ces fonctions soient générées pour vous (malheureusement, C++ ne supporte pas les choses comme la réflexion de Java). Vous pouvez regarder boost/serialization.

+0

Convainquez-moi pourquoi cela nécessitait un downvote! – Joshua

+0

Pour une seule structure c'est briser un papillon sur une roue, mais je pense qu'il ne méritait pas une downvote aussi, car il a écrit "pour le cas général". –

1

je ferais quelque chose comme:

struct serialized_data { 
    size_t s1_offset; 
    size_t s2_offset; 
    size_t s3_offset; 
    long l; 
    char strings[1]; 
}; 

serialized_data* serialize (data d) { 
    serialized_data* s = malloc(sizeof(serialized_data) + d.s1.length() + d.s2.length() + d.s3.length() + 3); 
    s->s1_offset = 0; 
    s->s2_offset = d.s1.length() + 1; 
    s->s3_offset = s2_offset + d.s2.length() + 1; 
    s->l = d.l; 
    strcpy(s->strings, d.s1.c_str()); 
    strcpy(s->strings + s->s2_offset, d.s2.c_str()); 
    strcpy(s->strings + s->s3_offset, d.s3.c_str()); 

    return s; 
} 
+0

N'oubliez pas de gérer le cas où quelqu'un passe dans des décalages/longueurs d'ordures dans votre code de désérialisation. –

0
struct data 
{ 
    std::string s1; 
    std::string s2; 
    std::string s3; 
    long l; 
}; 


int Write(FILE* file, const data* myData) 
{ 
    unsigned long length; 

    length = myData->s1.size(); 
    fwrite((void*) &length, sizeof(length), 1, file); 
    fwrite((void*) myData->s1.data(), length, 1, file); 
    ... // write the other strings and long here 
} 

int Read(FILE* file, data* myData) 
{ 
    unsigned long length; 
    char* buffer; 

    fread((void*) &length, sizeof(length), 1, file); 
    buffer = new char[length]; 
    length = fread(&buffer, length, 1, file); 
    myData.s1 = string(buffer, length); 
} 

Bien sûr, ne contrôle d'erreur et ce qui ne