22

My binary file looks like this.

00000000: 0000 0803 0000 ea60 0000 001c 0000 001c
00000010: 0000 0000 0000 0000 0000 0000 0000 0000

left column is address.

I just tried to read 0000 0803(=2051) as follows

ifstream if;
if.open("file");
uint32_t a;
if >> a;

As expected...It did not work :-(
a was just 0 after execution.
I tried long, int, unsigned int, unsigned long. All failed.

Why these are not working and how can I achieve the goal?

5
  • 3
    Did you check whether the file was opened correctly? What's the state of the stream after the read? (fail or bad state?) Commented Aug 18, 2015 at 7:24
  • 2
    remember about open mode - second argument to open (en.cppreference.com/w/cpp/io/ios_base/openmode). Commented Aug 18, 2015 at 7:26
  • 2
    And you need to know what endianness was used when saving the file. Little-endian (e.g. Intel x86): Least significant byte on lowest address, Big-endian (e.g. the internet): Most significant byte on lowest address. Commented Aug 18, 2015 at 7:29
  • If you're reading the MNIST image dataset from LeCun on an Intel PC, then you'll need to reverse the byte order as @ErikAlapää mentioned. Commented Apr 22, 2018 at 7:25
  • 2
    @plhn just a side note: maybe if is not a valid name for your ifstream variable... Commented Jun 13, 2018 at 6:32

2 Answers 2

37

You have two issues:

  1. Insuring you read the bytes you intend (no fewer, no more) from the stream.

    I'd recommend this syntax:

    uint32_t a;

    inFILE.read(reinterpret_cast<char *>(&a), sizeof(a));

  2. Insure you're interpreting those bytes with the correct byte order.

    Q: If you're on a PC, your CPU is probably little endian. Do you know if your data stream is also little-endian, or is it big endian?

    If the data is big-endian, I'd consider the standard networking functions to accomodate byte order: ntohl(), etc: http://www.retran.com/beej/htonsman.html

ALSO:

Follow Hcorg's and Daniel Jour's advice: don't forget about the "open mode" parameter, and don't forget to check for "file open" errors.

Sign up to request clarification or add additional context in comments.

4 Comments

Actually, there is 3 issues: he needs to read the data hexadecimal as well, which is probably the biggest problem.
It would be better to explain some reasons about first issue.(=Why do you recommend read function, not input stream?)
why doesn't >> work? is this a documented behavior?
@zhangxaochen >> is looking for the ASCII representation of the numbers, to read 42 it expects to see 0x34, 0x32 in the stream '4' and '2', not 0x2a
5

Open file in binary mode and then use read() method, something like:

uint32_t a;
ifstream file ("file", ios::in | ios::binary);
if (file.is_open())
{
     file.read ((char*)&a, sizeof(a));
}

5 Comments

error: cannot initialize a parameter of type 'char_type *' (aka 'char *') with an rvalue of type 'int32_t *' (aka 'int *'). What about it?
@LRDPRDX What about "what"? Did you ask question about your case and provide an example? (in my snippet there is no conversion to char, as well as no initialization).
I just tried to compile your snippet. And there was the error I printed above.
@LRDPRDX I do not have the opportunity to check (has no c++ compiler for Android in Galaxy Note-3)... but it is the definitely issue of pointer type conversion. Try to add explicit conversion for &a : file.read((char*)&a, sizeof(a));
Implicitely I was saying about it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.