【问题标题】:c++ read and write struct array with std::string into binary filec ++使用std :: string读取和写入struct数组到二进制文件中
【发布时间】:2015-05-06 08:38:34
【问题描述】:

我对 c++ 很陌生(这个问题是我作业的一部分)。

我需要将结构数组存储在二进制文件中并将它们读回。问题是我的结构包含std::string 字段。另一方面,我可以读取字符串,但之后什么也没有。这是我的结构定义:

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

这是我将这个结构的数组写入文件的代码:

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

这是我读回这个文件的代码部分:

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

据我了解,我需要运行这个循环来确定一个文件中存储了多少个结构。当我运行调试器时,我成功读取了id 字段、字符串大小和实际字符串。但是,我从来没有得到正确的 paidTaxes 字段(float 的类型),随后的循环返回给我垃圾。

提前致谢!

【问题讨论】:

    标签: c++ serialization struct fstream


    【解决方案1】:

    问题出在这一行

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

    这里打错字了

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

    你应该写 sz 字节,而不是 sizeof(sz)。您的代码还有一个问题。您将读取最后一条记录两次,因为 file.good() 将在最后一条记录之后返回 true。你可以这样读:

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

    【讨论】:

    • 谢谢!还有一个问题:在开头写存储数组大小以避免这个循环是否合理?我会读取数组大小,创建具有正确大小的结构数组并使用单循环来填充文件中的数据?
    • 是的,你可以做到这一点,很简单,很可靠
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 2022-01-28
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多