20

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?

jww
  • 97,681
  • 90
  • 411
  • 885
plhn
  • 5,017
  • 4
  • 47
  • 47
  • 3
    Did you check whether the file was opened correctly? What's the state of the stream after the read? (fail or bad state?) – Daniel Jour Aug 18 '15 at 07:24
  • 2
    remember about open mode - second argument to open (http://en.cppreference.com/w/cpp/io/ios_base/openmode). – Hcorg Aug 18 '15 at 07: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. – Erik Alapää Aug 18 '15 at 07: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. – DavidJ Apr 22 '18 at 07:25
  • 2
    @plhn just a side note: maybe `if` is not a valid name for your `ifstream` variable... – Alessandro Jacopson Jun 13 '18 at 06:32

2 Answers2

35

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.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Actually, there is 3 issues: he needs to read the data hexadecimal as well, which is probably the biggest problem. – Mark Jansen Aug 18 '15 at 07:53
  • It would be better to explain some reasons about first issue.(=Why do you recommend `read` function, not input stream?) – plhn Aug 18 '15 at 13:44
  • 4
    why doesn't `>>` work? is this a documented behavior? – zhangxaochen Feb 24 '17 at 03:02
  • 1
    @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 – pm100 Jun 25 '20 at 17:53
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));
}
VolAnd
  • 6,367
  • 3
  • 25
  • 43
  • 1
    error: cannot initialize a parameter of type 'char_type *' (aka 'char *') with an rvalue of type 'int32_t *' (aka 'int *'). What about it? – LRDPRDX Mar 30 '18 at 15:18
  • @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). – VolAnd Apr 01 '18 at 17:23
  • 2
    I just tried to compile your snippet. And there was the error I printed above. – LRDPRDX Apr 01 '18 at 18:34
  • @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));` – VolAnd Apr 02 '18 at 04:57
  • 2
    Implicitely I was saying about it. – LRDPRDX Apr 03 '18 at 05:37