2017-10-01 9 views
0

Je teste une structure personnalisée où il y a un champ de bits et un char * non signé (qui sera alloué plus tard).fwrite/fread struct avec bitfields et char *

Voici la structure:

struct test { 
    unsigned int field1 : 1; 
    unsigned int field2 : 15; 
    unsigned int field3 : 32; 
    unsigned int dataLength : 16; 
    unsigned char * data; 
} 

Le problème est quand j'ai essayé de sauver ce struct dans un fichier en hexadécimal.

Par exemple:

int writeStruct(struct test *ptr, FILE *f) { 

    // for data, suppose I know the length by dataLength : 
    // this throw me : cannot take adress of bit field 
    int count; 
    count = fwrite(&(ptr->field2), sizeof(unsigned int), 1, f); 

    // this throw me : makes pointer to integer without a cast 
    count = fwrite(ptr->field2, sizeof(unsigned int), 1, f); 

    // same for length 
    count = fwrite(htons(ptr->data) , ptr->dataLength, 1,f);  

    // so , how to do that ? 
} 

Le même problème va fread:

int readAnStructFromFile(struct test *ptr, FILE *f) { 
    // probably wrong 
    fread(ptr->field1, sizeof(unsigned int), 1, f); 
} 

Alors, comment puis-je écrire/lire struct comme ça?

Merci pour votre aide

PS pour fread, cela pourrait fonctionner s'il n'y avait pas ces bitfields: How to fread() structs?

+1

Lors de l'utilisation bitfields pour '' field1' et field2' semble logique, car ils ne sont pas bits standard -widths, cela a moins de sens pour 'field3' et' dataLenght', qui pourraient utiliser respectivement 'uint32_t' et' uint16_t'. Et si vous n'êtes pas sur un système contraint en mémoire, il n'y a souvent pas besoin de bitfields (et utilisez ensuite size_t) pour le membre 'dataLength') sauf si vous essayez de faire correspondre une autre structure de données (paquet réseau, structure sur disque, ou similaire). –

+0

C'est un exemple pour gérer plusieurs cas :). J'ai essayé de faire un paquet réseau personnalisé ^^ – jy95

+0

Avez-vous vraiment besoin de stocker le fichier au format binaire? Pourquoi pas quelque chose comme 'json', etc.? Ce qui serait plus facile à lire en raison de la structure de texte de fichier cohérente en utilisant 'fscanf' et' fprintf'. – AmeyaVS

Répondre

1

il n'y a pas moyen d'obtenir une adresse d'un champ de bits. La façon habituelle de le gérer est soit d'utiliser une variable temporaire sur les côtés lecture/écriture, soit de sauvegarder la structure entière en tant qu'entité unique. Avec température vars il se présente comme suit:

int count; 
int field2 = ptr->field2; 
count = fwrite(&field2, sizeof(unsigned int), 1, f); 
... 
int field1; 
fread(&field1, sizeof(unsigned int), 1, f); 
ptr->field1 = field1; 

ou pour toute struct:

count = fwrite(ptr, sizeof(struct test), 1, f); 
+0

merci: je vais tester votre première idée. Pensez-vous que l'ensemble struct fwrite ne fonctionnera pas à cause du pointeur à l'intérieur? – jy95

+0

Dans votre cas, l'écriture de structure entière ne fonctionnera pas. Il n'écrira pas les données elles-mêmes, seulement le pointeur de données qui n'a aucun sens. – Serge

+0

La suggestion est de le diviser en 2 parties: en-tête et les données. L'en-tête que vous seriez en mesure d'écrire dans son ensemble – Serge