Reading binary file data into struct object?

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):
06 00 FF FF FF FF


And what I would expect is this:
Size: 6
Data: 4294967295


But it gave me this:
Size: 6
Data: 65535


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.
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?
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.
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));
Thanks! That works well.
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.