Reading binary file data into struct object?
Jun 28, 2021 at 2:36pm UTC
Hello. I do not know if it's the right way to do this, but I have this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include <iostream>
#include <fstream>
typedef unsigned int u32;
typedef unsigned short u16;
struct MyStruct {
u16 Size;
u32 Data;
};
int main(int argc, char **argv) {
std::ifstream ifs("data.bin" , std::ios::binary);
if (!ifs) {
std::cout << "FATAL: File data.bin could not be opened.\n" ;
return 1;
}
MyStruct ms;
ifs.read(reinterpret_cast <char *>(&ms), 6);
if (ifs.gcount() != 6) {
std::cout << "Could not read 6 bytes." << std::endl;
return 1;
}
std::cout << "Size: " << ms.Size << std::endl;
std::cout << "Data: " << ms.Data << std::endl;
return 0;
}
And here is
data.bin (bytes):
And what I would expect is this:
But it gave me this:
I don't know what's wrong, but I think it's reading bytes 4 & 5. Is the code the problem? Also, FWIW sizeof u32 returns 4 and sizeof u16 returns 2.
Jun 28, 2021 at 2:42pm UTC
The compiler is inserting two bytes of padding between 'size' and 'data'. You need to tell it not to do this. Which compiler are you using?
Jun 28, 2021 at 2:48pm UTC
I'm pretty sure that I am using MinGW G++, but I am in eclipse and forgot what I selected at the creation of this project. I generally use MinGW G++ though.
Jun 28, 2021 at 2:50pm UTC
In GCC you can add the attribute packed at the end of a struct to disable padding. E.g.
1 2 3 4
struct MyStruct {
u16 Size;
u32 Data;
} __attribute__((packed));
Jun 28, 2021 at 2:53pm UTC
Thanks! That works well.
Jun 28, 2021 at 5:55pm UTC
How did you write the information to the file?
You really shouldn't be using that magic number in your read() call, use the actual sizeof the structure.
1 2
MyStruct ms;
ifs.read(reinterpret_cast <char *>(&ms), sizeof (ms));
Also you may want to consider using the standard fixed size destinations for the types instead of the typedef.
Topic archived. No new replies allowed.