在二进制文件 C++ 中写入和加载结构向量

2021-12-21 00:00:00 binary struct vector c++

我真的需要你的帮助.我的代码中有以下结构:

I really need your help. I have the following structs in my code:

    struct Field{
        char name[20];
        int type;
        int length;
    };

    struct Record{
        vector<Field> structure;
        vector<string> info;
    };

我想要做的是将我的结构记录向量存储在一个二进制文件中并成功加载它.问题是我的结构里面有两个向量,它们给我带来了一些麻烦.你能帮我吗?

What I want to do is to store a vector of my struct Record inside a binary file and to successfully load it back. The problem is that my struct has two vectors inside of it and they are causing me some trouble. Can you help me out?

推荐答案

您基本上只是编写将结构写入流的函数.如果是 POD,首先你写下结构的大小.

You basically just write functions that would write the structure to a stream. First you write the size of the structure if it's a POD.

如果不是 POD,你写下每个元素的大小,然后你写下元素的数据.

If it's not POD, you write the size of each element then you write the data for the element.

下面你可以看到对于writevecfield,它先写了向量的大小.然后它将整个 POD 结构写入流.writesvecstring 首先写入向量的大小.然后它遍历向量并写入:每个字符串的大小,然后是其内容.

Below you can see for writevecfield, it writes the size of the vector first. Then it writes the entire POD structure to the stream. writesvecstring writes the size of the vector first. Then it goes through the vector and writes: the size of each string followed by its contents.

阅读,你做相反的事情.readvecfield 从文件中读取向量的大小,因为它是第一个写入的内容.读完之后,我们调整向量的大小并读取大小".字段"的数量构造成新向量.

To read, you do the opposite. readvecfield reads the size of the vector from the file because it was the first thing written. After reading it, we resize the vector and read "size" amount of "Field" structures into the new vector.

为了读取字符串,我们也做相反的事情.readvecstring 首先从文件中读取向量的大小.它将向量调整为读取大小.接下来它循环大小"次数,因为这是文件中的字符串数量.

To read the strings, we do the opposite as well. readvecstring reads the size of the vector from the file first. It resizes the vector to the read size. Next it loops "size" amount of times because that's the amount of strings in the file.

然后我们读取字符串的大小,调整字符串的大小并将内容读入该字符串.然后我们将它添加到向量并移动到下一个字符串:首先读取大小,调整字符串大小,读取内容,添加到向量..

We then read the size of the string, resize a string and read the contents into that string. We then add that to the vector and move onto the next string: read the size first, resize a string, read contents, add to vector..

#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>

using namespace std;


struct Field
{
    char name[20];
    int type;
    int length;
};

struct Record
{
    vector<Field> structure;
    vector<string> info;
};

void writevecfield(ostream& os, const vector<Field> &vec)
{
    typename vector<Field>::size_type size = vec.size();
    os.write((char*)&size, sizeof(size));
    os.write((char*)&vec[0], vec.size() * sizeof(Field));
}

void readvecfield(istream& is, vector<Field> &vec)
{
    typename vector<Field>::size_type size = 0;
    is.read((char*)&size, sizeof(size));
    vec.resize(size);
    is.read((char*)&vec[0], vec.size() * sizeof(Field));
}

void writevecstring(ostream& os, const vector<string> &vec)
{
    typename vector<string>::size_type size = vec.size();
    os.write((char*)&size, sizeof(size));

    for (typename vector<string>::size_type i = 0; i < size; ++i)
    {
        typename vector<string>::size_type element_size = vec[i].size();
        os.write((char*)&element_size, sizeof(element_size));
        os.write(&vec[i][0], element_size);
    }
}

void readvecstring(istream& is, vector<string> &vec)
{
    typename vector<string>::size_type size = 0;
    is.read((char*)&size, sizeof(size));
    vec.resize(size);

    for (typename vector<string>::size_type i = 0; i < size; ++i)
    {
        typename vector<string>::size_type element_size = 0;
        is.read((char*)&element_size, sizeof(element_size));
        vec[i].resize(element_size);
        is.read(&vec[i][0], element_size);
    }
}



void WriteRecord(ostream& out, const Record& r)
{
    writevecfield(out, r.structure);
    writevecstring(out, r.info);
}

void ReadRecord(istream& in, Record& r)
{
    readvecfield(in, r.structure);
    readvecstring(in, r.info);
}


int main()
{
    Record R;

    Field first = {"HELLO", 1, 20};
    Field second = {"WORLD", 2, 40};
    R.structure.push_back(first);
    R.structure.push_back(second);
    R.info.push_back("INFO FOR HELLO");
    R.info.push_back("INFO FOR WORLD");

    std::ofstream out("C:/Users/***/Desktop/Test.bin", std::ios::out | std::ios::binary);
    WriteRecord(out, R);
    out.close();

    Record RR;
    std::ifstream in("C:/Users/***/Desktop/Test.bin", std::ios::in | std::ios::binary);
    ReadRecord(in, RR);
    in.close();

    for (int i = 0; i < RR.structure.size(); ++i)
    {
        std::cout<<"Name:   "<<RR.structure[i].name<<"
";
        std::cout<<"Type:   "<<RR.structure[i].type<<"
";
        std::cout<<"Length: "<<RR.structure[i].length<<"
";
        std::cout<<"INFO:   "<<RR.info[i]<<"

";
    }
}

相关文章