2

I'm very new to c++ (and the question is a part of my homework).

I need to store an array of structs in a binary file and read them back. The problem is that my struct contains std::string field. On the other side I can read the string, but nothing after it. Here is my structure definition:

struct Organization {
    int id;
    string name;
    float paidTaxes;
};

and here is the code where I write array of this struct to a file:

void writeToFile(Organization *orgs, int n) {
    ofstream file("orgs.bin", ios::out | ios::binary);
    if (!file) { return; }
    for (int i = 0; i < n; i++) {
        // determine the size of the string
        string::size_type sz = orgs[i].name.size();
        file.write(reinterpret_cast<char*>(&orgs[i].id), sizeof(int));
        // write string size
        file.write(reinterpret_cast<char*>(&sz), sizeof(string::size_type));
        // and actual string
        file.write(orgs[i].name.data(), sizeof(sz));
        file.write(reinterpret_cast<char*>(&orgs[i].paidTaxes), sizeof(float));
    }
    file.close();
}

and here is the code part where I'm reading this file back:

count = 0;
Organization org;
ifstream file;
file.open("orgs.bin", ios::binary);
while (file.good()) {
    string::size_type sz;
    file.read(reinterpret_cast<char*>(&org.id), sizeof(int));
    file.read(reinterpret_cast<char*>(&sz), sizeof(string::size_type));
    org.name.resize(sz);
    file.read(&org.name[0], sz);
    file.read(reinterpret_cast<char*>(&org.paidTaxes), sizeof(float));
    count++;
}

As far as I understand, I need to run this loop to determine how many structs are stored in a file. When I run debugger, I successfully read id field, string size and actual string. However, I never get proper paidTaxes field (type of float) and subsequent loops return me junk.

thanks in advance!

1 Answer 1

1

The problem is in this line

file.write(orgs[i].name.data(), sizeof(sz));

Here is a typo, insted use

file.write(orgs[i].name.data(), sz);

You shoud write sz bytes, but not sizeof(sz). There is also one more problem with your code. You will read the last record twice, because file.good() will return true after the last record. You can read like that:

    while (file.good()) {
    string::size_type sz;
    if( !file.read(reinterpret_cast<char*>(&org.id), sizeof(int)) )
        break;
    file.read(reinterpret_cast<char*>(&sz), sizeof(string::size_type));
    org.name.resize(sz);
    file.read(&org.name[0], sz);
    file.read(reinterpret_cast<char*>(&org.paidTaxes), sizeof(float));
    count++;

    std::cout << org.id << " " << org.name << " " << org.paidTaxes << std::endl;
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks! One more question: would it be reasonable to write stored array size at the beginning to avoid this loop? I would read array size, create struct array with correct size and use single loop to fill the data from file?
Yes, you can do this, that is pretty simple and realiably

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.