Question

I'm trying to read data from binary file using folloing code:

fstream s;
s.open(L"E:\\test_bin.bin", ios::in | ios::binary);
int c = 0;
while (!s.eof())
{
    s >> c;
    cout << c;
}

c is always 0 (current value of c. If I set c to 1, result is 1). File exists and it has data that is not zeros, so problem is not at file. I can read this file using fread and using s.get(), but why given code not working?

Was it helpful?

Solution

Using the ios::binary flag doesn't necessarily mean that you read and write binary data. Take a look at https://stackoverflow.com/a/2225612/2372604 . ios::binary means "data is read or written without translating..."

What you probably want to do is use s.read(...). In your case the stream operator attempt to read a complete integer (something like "1234") rather then X number of bits that will fit into your integer.

For reading 4 bytes, something like the folling might work (untested):

int n;
while (s.read((char*) &n, 4) && s.gcount() != 0 ) {}

OTHER TIPS

What's wrong with:

int c = 0;
char ch;
int shift = 32;
while ( s.get( ch ) && shift != 0 ) {
    shift -= 8;
    c |= (ch & 0xFF) << shift;
}
if ( shift != 0 ) {
    //  Unexpected end of file...
}

This is the (more or less) standard way of reading binary 32 bit integers off the network. (This supposes that native int is 32 bits 2's complement, of course.)

Some protocols use different representation of 32 bit ints, and so will require different code.

As for your original code: the test s.eof() is always wrong, and >> is for inputting text; in particular, it will skip leading whitespace (and binary data may contain codes which correspond to whitespace).

I might also add that you should ensure that the stream is imbued with the "C" locale, so that no code translation occurs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top