0

I am testing a custom structure where there is bitfield and a unsigned char * (that will be allocated later).

Here is the structure :

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

The problem is when I tried to save this struct inside a file in hex.

For example :

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 ?
}

The same problem goes to fread :

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

So , how can I write/read struct like this ?

Thanks for your help

PS for fread, this could work if there wasn't these bitfields: How to fread() structs?

Rob
  • 14,746
  • 28
  • 47
  • 65
jy95
  • 773
  • 13
  • 36
  • 1
    While using bitfields for `field1` and `field2` seems to make sense, since they are not standard bit-widths, it makes less sense for `field3` and `dataLenght`, which could use `uint32_t` and `uint16_t` respectively. And if you're not on a memory-constrained system, there's often no need for bitfields at all (and then use `size_t` for the `dataLength` member) unless you are trying to match some other data-structure (network packet, on-disk structure, or similar). – Some programmer dude Oct 01 '17 at 13:57
  • It is an example to handle several case :). I tried to make a custom network packet ^^ – jy95 Oct 01 '17 at 14:01
  • Do you really require to store the file in Binary format? Why not something like `json`, etc.? Which would be easier to read back due to consistent file text structure using `fscanf` and `fprintf`. – AmeyaVS Oct 01 '17 at 14:01
  • Yes, it should be in binary so that something else transfers it .. – jy95 Oct 01 '17 at 14:02
  • Do you understand what the `s` stands for in `htons()`? – Iharob Al Asimi Oct 01 '17 at 14:04
  • I don't think so ... short ? – jy95 Oct 01 '17 at 14:06
  • 1) You cannot take the address of a bitfield, it has no address. 2) you can fwrite() the entire structure in one call,though. – wildplasser Oct 01 '17 at 14:25
  • fwrite with an pointer inside the struct ? The last time I have done something like that, it didn't work ^^ – jy95 Oct 01 '17 at 14:27

1 Answers1

1

there is no way to get an address of a bitfield. The usual way to handle it is to either use a temporary variable on read/write sides or just to save the whole struct as a single entity. With temp vars it looks like the following:

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;

or for the whole struct:

count = fwrite( ptr, sizeof(struct test), 1, f);
Serge
  • 11,616
  • 3
  • 18
  • 28
  • thanks : i will test your first idea. Do you think the whole struct fwrite will not work because of the pointer inside ? – jy95 Oct 01 '17 at 14:26
  • In your case the whole struct write will not work. It will not write the data itself, just the data pointer which makes no sense. – Serge Oct 01 '17 at 14:39
  • The suggestion is to split it in 2 parts: header and the data. The header you would be able to write as a whole – Serge Oct 01 '17 at 14:40