1

I am studying binary file of C++ nowadays. I made a example code for it, but it does not work well.

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

int main() {
    ofstream writeFile;
    ifstream readFile;
    int temp = 1;

    writeFile.open("file.dat", ios::binary);

    for (int i = 5; i <= 10 ; i++) // range 5 to 10
        writeFile.write((char*)(&i), sizeof(i));

    writeFile.close();

    readFile.open("file.dat", ios::binary);
    readFile.seekg(0);
    while (!readFile.eof()) {
        readFile.read((char*)(&temp), sizeof(temp));
        cout << "temp: " << temp << endl;
        readFile >> ws;
    }
    readFile.close();

    system("pause");
    return 0;
}

Here is the result:

temp: 5
temp: 6
temp: 7
temp: 8
temp: 167772160
temp: 167772160

When I change the range not to include 9 (for example, 5 to 8), it works well. Also, When I make the same code with double type, it works well. So I think the integer 9 is problem. Can you tell me why?

0

2 Answers 2

4

readFile >> ws; discards white space, which is non-sense for a binary stream. In this case, the character value 9 (which is '\t') is skipped, corrupting your stream. Simply remove that line.

The second problem is you are not checking the state of the stream between reading and displaying the value. EOF is only detected after a read would exceed the end of the file. This is why you get your invalid value twice, the second time the read fails and simply leaves temp with it's previous value. See this question for a more details.

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

2 Comments

The value 9 is actually \t. 10 is \n. The fact that both are considered white space is what causes the issue.
Or rather, readFile >> ws skips over the \t character only, then reading the four bytes 00 00 00 0a, interpreted as a little-endian 4-byte integer is the value 167772160. This is still well defined (I believe). However, the next read attempt reads beyond the EOF. That is UB, and displaying 167772160 is a valid form of undefined behavior.
1

The answer by François Andrieux already has the answer to the question of why your code behaves the way it does.

Here are couple of methods to fix the problem.

  1. Use a for loop to read the numbers. It mirrors the loop used to write to it.

    readFile.open("file.dat", ios::binary);
    for (int i = 5; i <= 10 ; i++)
    {
       readFile.read((char*)(&temp), sizeof(temp));
       cout << "temp: " << temp << endl;
    }
    readFile.close();
    
  2. Use the while loop correctly.

    readFile.open("file.dat", ios::binary);
    while (readFile.read((char*)(&temp), sizeof(temp)))
    {
       cout << "temp: " << temp << endl;
    }
    readFile.close();
    

Comments

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.