Search code examples
c++filec++11fstreamreinterpret-cast

Failed to read data using reinterpret_cast<char*> in C++


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

int main(){

// write file

    string file_name = "random_fstream.dat";
    ofstream file(file_name, ios_base::out | ios_base::binary);

    if (!file) {return EXIT_FAILURE;}

    int r = 2; 
    int c = 3;

    file.write(reinterpret_cast<char*>(&r),sizeof(r));
    file.write(reinterpret_cast<char*>(&c),sizeof(c));

//------------------------------------------------

// read file

    ifstream in(file_name, ios_base::in | ios_base::binary);
    if (!in) {return EXIT_FAILURE;}

    int x = 0;
    int y = 0;

    in.read(reinterpret_cast<char*>(&x),sizeof(x));
    in.read(reinterpret_cast<char*>(&y),sizeof(y));

    cout << x << y << endl;


    return 0;
} 

I was trying to practice write and read file in C++. First step was to write int value 2 and 3 into the file with binary form. Second step was to read the two number from that file.

Then I got x and y valued both equal to 0, but I expected to receive x=2 and y=3. Where did I do wrong?


Solution

  • As have been pointed out in comments, you have at least two bugs:

    The first problem is in your reads: both your reads use the address of x and the size of y, which I'm sure is just a typo.

    Second, you have to close() the file you opened for writing (or at least, flush your writes (sync()) before reading that same data again, but that needs a whole lot of caution and special rules.) Anyways, you need to close the file, either by letting the handle (file in this case) fall out of scope and getting its destructor called, or calling file.close() yourself (after the writes.)

    To prevent this problem, you generally have to check for errors every time you do any I/O. To do that, you can use the name of your file handle like a boolean variable, e.g.:

    in.read(reinterpret_cast<char*>(&x),sizeof(x));
    if (!in)
        cerr << "First read failed." << endl;
    in.read(reinterpret_cast<char*>(&y),sizeof(y));
    if (!in)
        cout << "Second read failed." << endl;
    

    I you want to know what actually is going on, the class std::istream has an explicit conversion to bool that returns whether the last operation succeeded or not (or whether the stream is in a readable/good condition or not.) There is also a host of member functions defined for C++ streams (both input and output) that help you check for errors, the end of a stream, etc., e.g. bad(), good(), fail(), eof(), etc.

    Again, just remember that any I/O operation can fail at any time for various reasons, so check its status!