简体   繁体   中英

c++ read and write struct array with std::string into binary file

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!

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM