oldjohn1994
oldjohn1994

Reputation: 389

Reversing long read from file?

I'm trying to read a long (signed, 4 bytes) from a binary file in C++. My main concerns are: portability (longs are different sizes on different platforms), when you read from binary files w/ std::ifstream, it reverses the byte order (to my machine's endianness).

I understand for data types like unsigned int, you can simply use bitwise operators and shift and AND each byte to reverse the byte order after being read from a file.

I'm just not sure what I'd do for this: Currently my code will give a nonsense value:

long value;
in.seekg(0x3c);
in.read(reinterpret_cast<char*>(&value), sizeof(long));

I'm not sure how I can achieve portability (I read something about unions and char*) and also reverse the signed long it reads in.

Thanks.

Upvotes: 0

Views: 150

Answers (3)

selbie
selbie

Reputation: 104569

Rather than using long, use int32_t from <stdint.h> to directly specify a 32-bit integer. (or uint32_t for unsigned).

Use htonl and ntohl as appropriate to get to/from network byte order.

Better:

int32_t value;
in.seekg(0x3c);
in.read(reinterpret_cast<char*>(&value), sizeof(value));
value = ntohl(value); // convert from big endian to native endian

Upvotes: 0

Sean
Sean

Reputation: 62532

Since cross platform support is important to you I'd recommend using cstdint to specify the size of your types. You'll be able to say int32_t x (for example) and know you are getting 32 bits of data.

Regarding the endianness of the data I'd recommend standardizing on a format (eg all data is written in little endian format) and wrapping your I/O operations in a class and using it to read/write the data. Then use a #define to decide how to read the data:

#ifdef BIG_ENDIAN
  // Read the data that is in little endian format and convert

#else
  // We're in little endian mode so no need to convert data
#endif

Alternatively you could look at using something like Google Protobuf that will take care of all the encoding issues for you.

Upvotes: 0

Alexey Voinov
Alexey Voinov

Reputation: 1116

I'd suggest you use functions like htonl, htnons, ntohl and ntohs. These are used in network programming to achieve just the same goal: portability and independence of endianness.

Upvotes: 0

Related Questions