简体   繁体   English

如何将数据从二进制文件中的另一个 class 中的结构放入向量中

[英]How to put data into a vector from a structure in another class that is in a binary file

class Work{
public:

    struct dane {
        int id;
        char typeOfWork[5];
        char Title[50];
        char Author_lastName[40];
        char Author_name[50];
        int year;
        char Promotor_lastName[30];
        char Promotor_name[40];
        char keyWords[50];
        char summary[1000];
    };

    dane dane1;
};

In another class, I enter all values to this variables and save it to a binary file.在另一个 class 中,我将所有值输入该变量并将其保存到二进制文件中。

I want to save all this input into a vector in another class called liblary :我想将所有这些输入保存到另一个名为liblary的 class 中的向量中:

class liblary : Work{
    vector<Work> vec; // here is problem i want to keep all this inputs in this vector
    int how_many_works;
    void get_data(){
        //
        // Up here i have inputs for all this variables but I didn't copy it 
        //
        ofstream plik;
        
        plik.open("dane.dat",ios::out | ios::binary | ios::app);
        if(plik.is_open()){
            plik.write((const char *) &dane1, sizeof(dane));
            vec.push_back(dane); // Something like that to store all works in this vector but this ofc don;t work
            plik.close();
        }
    };

Ofc, in method get_data() , I didn't copy here all inputs of data, I did it just to show that that is in the liblary class and includes a binary file. Ofc,在方法get_data()中,我没有在这里复制所有数据输入,我这样做只是为了表明它在liblary中并包含一个二进制文件。 This is a liblary system for a student thesis.这是一个学生论文的图书馆系统。 I want this in vector because later I must add modify and searching methods in this OOP program.我想要这个在vector中,因为稍后我必须在这个 OOP 程序中添加修改和搜索方法。

Main question: How I can put all inputs what are getting saved to binary file, to vector.主要问题:我如何将所有输入的内容保存到二进制文件、向量中。

Okay, your code is a little odd, but it's not too bad.好的,您的代码有点奇怪,但还算不错。 I'm going to ignore the oddness because you might actually have a reason for it.我将忽略这种奇怪之处,因为您实际上可能有理由这样做。

Your vector is std::vector<Work> , but you're doing a push_back of a dane .你的矢量是std::vector<Work> ,但你正在做一个push_back of a dane You either need to change to a vector<Work::dane> or do vec.push_back(*this) instead.您需要更改为vector<Work::dane>或改为执行vec.push_back(*this)

I would make one other change.我会做另一个改变。 I don't know why you have a nested structure, but that's fine.我不知道你为什么有嵌套结构,但这很好。 I think it's dangerous to have dane dane the way you do, and I think it's doubly-dangerous you're leaving the contents willy-nilly.我认为让dane dane像你这样很危险,而且我认为你随意离开内容物是双重危险的。

I'd do this:我会这样做:

std::vector<dane> vec;
if(plik.is_open()){
    dane myDane;   // This is new, and then I use it instead of dane1
    // populate myDane as needed...
    plik.write((const char *) &myDane, sizeof(myDane));
    vec.push_back(myDane); // Something like that to store all works in this vector but this ofc don;t work
    plik.close();
}

That is, I'd use a local copy of your dane so you're not mucking with the one inside your object -- unless there's a good reason you want it to be mucked with while loading your vector.也就是说,我会使用你的dane的本地副本,这样你就不会在你的 object 中使用它 - 除非你有充分的理由希望在加载你的矢量时使用它。

Since you append the data I assume you want to load the data stored in a previous run.因为你 append 数据我假设你想要加载存储在上一次运行中的数据。 In this case open the file for both reading and writing, and read the elements from the file first and simply store any additional data written in the vector:在这种情况下,打开文件进行读写,首先从文件中读取元素,然后简单地存储写入向量中的任何附加数据:

Simplified example only setting the summary of a single element, appending it and printing all summaries:简化示例仅设置单个元素的摘要,附加它并打印所有摘要:

struct dane {
    int id;
    char typeOfWork[5];
    char Title[50];
    char Author_lastName[40];
    char Author_name[50];
    int year;
    char Promotor_lastName[30];
    char Promotor_name[40];
    char keyWords[50];
    char summary[1000];
};

class Library
{
    std::vector<dane> m_contents;
    std::fstream m_file;
public:
    Library(std::filesystem::path const& fileName)
    {
        // open file with
        // - input pos at the end (we want to know the number of elements) -> ate
        // - output pos at the end (we want to append data) -> app
        // - for reading and writing -> (in | out)
        // - no special treatment of line breaks -> binary
        m_file.open(fileName, std::ios::out | std::ios::in | std::ios::binary | std::ios::app | std::ios::ate);
        if (!m_file.is_open())
        {
            throw std::runtime_error("could not open file " + fileName.string());
        }
        
        auto existingDataSize = m_file.tellg();
        if ((existingDataSize % sizeof(dane)) != 0)
        {
            throw std::runtime_error("corrupted data in file " + fileName.string());
        }
        m_contents.resize(existingDataSize / sizeof(dane));
        m_file.seekg(0, std::ios::beg);
        m_file.read(reinterpret_cast<char*>(m_contents.data()), existingDataSize);
    }

    void WriteElement(dane const& element)
    {
        m_file.write(reinterpret_cast<char const*>(&element), sizeof(element));
        m_contents.emplace_back(element);
    }

    void Print() const
    {
        for (auto& d : m_contents)
        {
            std::cout << d.summary << '\n';
        }
    }
};

int main()
{
    Library lib("lib.dat");

    dane d;
    std::cin >> d.summary;
    lib.WriteElement(d);
    lib.Print();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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