I’m trying to read a binary file which is a series of bytes and longs encoded in little endian format.
I had assumed that I could use an ifstream opened in ios::binary mode for this, but apparently I cannot: When I try to read a long, it sets the failbit and throws an exception.
I do not understand why it is doing this.
This is my code:
std::string fname = (
boost::format(
(
boost::filesystem::initial_path()
/ "maps"
/ "w%02d.map"
)
.string()
)
% mapNum
)
.str();
if (!boost::filesystem::exists(fname))
throw std::runtime_error("No such map " + fname + "!");
std::ifstream file;
file.exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit);
file.open(fname, std::ios::in | std::ios::binary);
char header[4];
file.read(header, 4);
if (!(header[0] == '!' && header[1] == 'I' && header[2] == 'D' && header[3] == '!'))
throw std::runtime_error(fname + " is not a valida map file!");
unsigned short int RLEWtag = 0;
file >> RLEWtag;
and these are the first 10 bytes of the file: 21 49 44 21 CD AB 40 00 40 00
If it matters, I’m running this in VS2010 on 64 bit Windows 7.
You’re using formatted input (i.e. the stream extraction operator,
operator>>), which expects textual data; instead you need to use unformatted input, just as you did to read the header:Or, more succinctly (thanks @KerrekSB),