0

I am trying to replace a double value that is on the 32th byte in the binary file. In the below setup, the size of MyStruct is 24 bytes. Therefore, the 32th byte in file should be the Weight member variable of the 2nd struct. Right now when I execute, I am getting the strange output. I am expecting my 2nd struct to have the new weight value of 250 instead of 200:

#include <iostream>
#include <fstream>

using namespace std;

struct MyStruct
{
    int Grade;
    double Weight;
    char Gender;
};

int main()
{
    MyStruct* lStruct = new MyStruct{ 1, 100, 'M' };
    MyStruct* lStruct2 = new MyStruct{ 2, 200, 'F' };;

    fstream InFile;
    InFile.open("test.txt", ios::in | ios::out | ios::binary);
    InFile.write(reinterpret_cast<char*>(lStruct), sizeof(MyStruct));
    InFile.write(reinterpret_cast<char*>(lStruct2), sizeof(MyStruct));


    InFile.seekp(32, ios::beg);
    double Weight = 250;
    InFile.write(reinterpret_cast<char*>(&Weight), sizeof(double));

    InFile.seekg(0, ios::beg);
    InFile.read(reinterpret_cast<char*>(lStruct), sizeof(MyStruct));
    InFile.seekg(24, ios::beg);
    InFile.read(reinterpret_cast<char*>(lStruct2), sizeof(double));

    cout << lStruct->Grade<< endl;
    cout << lStruct->Weight << endl;
    cout << lStruct->Gender<< endl;
    cout << endl;

    cout << lStruct2->Grade<< endl;
    cout << lStruct2->Weight << endl;
    cout << lStruct2->Gender<< endl;
    cout << endl;

    return 0;
}

Output:

1

100

M

2

200

F

What is the problem?

Bonus question: is seekp(32, ios::beg) equivalent to seekp(-16, ios::end)? (can I use negative away-from end)?

Lamba Dawet
  • 137
  • 3
  • So what's wrong with the Q? – Lamba Dawet Oct 09 '19 at 16:05
  • 2
    Check your sizes again. – molbdnilo Oct 09 '19 at 16:08
  • You said, "In the below setup, the size of MyStruct is 24 bytes. Therefore, the 32th byte in file should be the Weight member variable of the 2nd struct." Because compilers may add padding to the struct, that is not necessarily true. See here: https://stackoverflow.com/questions/5397447/struct-padding-in-c – jjramsey Oct 09 '19 at 16:13
  • @molbdnilo Dammit copy/paste :D It turned out to be a typo.. Thanks – Lamba Dawet Oct 09 '19 at 16:15
  • Your approach is very fragile and ignores any potential padding within the struct. You are only guaranteed that there will be no padding before the *first* member of a struct. Further, changing the order of member may well change the size of your struct. You members are `int - 4 bytes`, `doube - 8 bytes`, and `char - 1 byte`. Unless something is forcing 8-byte alignment of members within the struct, your double (assuming no padding) will start at the 28th byte -- if your struct is really 24 bytes in size). Check the size with members ordered as `double, int, char`. – David C. Rankin Oct 09 '19 at 16:17
  • What happens if `test.txt` doesn't exist? How do you fix it? – David C. Rankin Oct 09 '19 at 16:53
  • @LambaDawet did you now solve this problem? I suggest you use [offsetof()](https://en.cppreference.com/w/cpp/types/offsetof) instead of relying on a certain member being in a certain place. Also this way your program won't break if you reorder the members of `MyStruct` od add new members. – Lukas-T Oct 09 '19 at 17:18
  • @churill Yes, it was a typo in my `sizeof(double)`, it should be `sizeof(MyStruct)` but thanks – Lamba Dawet Oct 10 '19 at 13:39

0 Answers0