Cannot read simple binary integers from file? (C++

2019-04-06 20:29发布

问题:

My code is simply as this:

UPDATED:

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char **argv)
{
  ifstream r("foo.bin", ios::binary);
  ofstream w("foo.bin", ios::binary);
  int i;

  int ints[10] = {0,1,2,3,4,5,6,8,9};
  w.write((char*)&ints, sizeof(ints));

  int in_ints[10];
  r.read((char*)&in_ints, sizeof(in_ints));

  for(i = 0;i < 10;i++) {
    cout << in_ints[i] << " ";
  }
  cout << endl;

  return 0;
}

Now, the write portion appears to be successful, for example running the od command with 32 bit longs (my system is 32 bit) will display the correct sequence, including a hex dump.

Reading however, I get random sequences such and negative integers that should not happen (it is split up, and mostly zeros as my integers are small, the sign bits should not be on.)

Do you see why my read method has failed to work, when it is really an opposite of my write method?

回答1:

try w.flush() or w.close() before r.read. the problem is when you write it usually bufferes text and doesn't save it in file. so there is nothing realy in file for r.read.



回答2:

This code:

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    {
        ofstream w( "foo.txt" );
        int ints[10] = {0,1,2,3,4,5,6,8,9};
        w.write((char*)&ints, sizeof(ints));
    }
    {
        ifstream r( "foo.txt" );
        int in_ints[10];
        r.read((char*)&in_ints, sizeof(in_ints));
        for( int i = 0; i < 10; i++) {
            cout << in_ints[i] << " ";
        }
    }
}

prints:

0 1 2 3 4 5 6 8 9 0

Note there are some numbers missing from your initialisation.



回答3:

Data written to a file isn't necessarily visible to other streams (in the same process or not) until the file is closed, or at least flushed. And if the file "foo.bin" doesn't exist before you start the program, opening it for reading will fail (and so all further use will be a no-op). Your program violates one of the most basic rules of programming: if anything can fail, always check that it hasn't before continuing. You don't check any of the results of your IO.

I might also add that reading and writing data this way is very, very fragile, and can generally only be guaranteed to work within the same process—even recompiling with a different version of the compiler or different compiler options may cause the data representation to change, with the results that you won't be able to read data written earlier. In the case of arrays of int, of course, this is highly unlikely as long as you don't change machine architectures. But in general, if you'll need to reread the data in the future, it's a technique best avoided. (The (char*) are reinterpret_cast, and as we know, reinterpret_cast is a very strong signal that there is a portability issue.)