如何在二进制文件中读/写结构? [英] How to read / write a struct in Binary Files?

查看:173
本文介绍了如何在二进制文件中读/写结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临一个小问题。我有一个结构,它有一个向量。注意,向量是每次迭代的动态。现在,在一个特定的迭代中,如何将包含大小为n的向量的struct存储到二进制文件?



此外,向量的大小,如何从二进制文件检索,struct变量包含所有存储的元素的向量?



我可以存储一些东西到二进制文件(我可以看到大小增加时,写),但当我试图检索回元素,我得到的向量的大小为零。



不幸的是,我必须使用标准STL实现这一点,而不使用任何第三方库。

解决方案

p>您应该查看 Boost序列化



如果您无法使用第三方库,您必须知道C ++不支持直接序列化。这意味着您必须自己做。



本文介绍了一种将自定义对象序列化到磁盘并将其检索回来的好方法。 本教程向您展示了如何立即使用 fstream 。 / p>

这是我的尝试:



EDIT :因为OP询问如何存储/检索多于记录我决定更新原来的代码。



那么,改变了什么?现在有一个数组 student_t apprentice [3]; 来存储3个学生的信息。整个阵列被序列化到磁盘,然后将其全部加载回RAM,在这里可以读取/搜索特定的记录。注意,这是一个非常小的文件(84字节)。我不建议在搜索大文件上的记录时使用此方法。

  #include< fstream& 
#include< iostream>
#include< vector>
#include< string.h>

using namespace std;


typedef struct student
{
char name [10];
int age;
vector< int>等级;
} student_t;

int main()
{
student_t apprentice [3];
strcpy(apprentice [0] .name,john);
apprentice [0] .age = 21;
apprentice [0] .grades.push_back(1);
apprentice [0] .grades.push_back(3);
apprentice [0] .grades.push_back(5);

strcpy(apprentice [1] .name,jerry);
apprentice [1] .age = 22;
apprentice [1] .grades.push_back(2);
apprentice [1] .grades.push_back(4);
apprentice [1] .grades.push_back(6);

strcpy(apprentice [2] .name,jimmy);
apprentice [2] .age = 23;
apprentice [2] .grades.push_back(8);
apprentice [2] .grades.push_back(9);
apprentice [2] .grades.push_back(10);

//将struct序列化为student.data
ofstream output_file(students.data,ios :: binary);
output_file.write((char *)& apprentice,sizeof(apprentice));
output_file.close();

//从中读取
ifstream input_file(students.data,ios :: binary);
student_t master [3];
input_file.read((char *)& master,sizeof(master));

for(size_t idx = 0; idx <3; idx ++)
{
//如果要搜索特定记录,
//在这里做! if(idx == 2)...

cout< Record#<< idx<< endl;
cout<< Name:<< master [idx] .name<< endl;
cout<< 年龄:< master [idx] .age< endl;
cout<< 成绩:< endl;
for(size_t i = 0; i< master [idx] .grades.size(); i ++)
cout< master [idx] .grades [i]< ;
cout<< endl<< endl;
}

return 0;
}

输出

 记录#0 
名称:john
年龄:21
成绩:
1 3 5

记录#1
名称:jerry
年龄:22
成绩:
2 4 6

记录#2
名称:jimmy
年龄:23​​
成绩:
8 9 10

转储二进制文件

  $ hexdump -c students.data 
0000000 john \0 237 {\0 { 025 \0 \0 \0
0000010( \b 4 \b 8 \bjerr
0000020 y \0 \0 | \0 026 \0 \0 \0 @ \b
0000030 L \b P \bjimmy \\ \\ 0 \0 \0
0000040 6 \0 027 \0 \0 \0 X \bd \b
0000050 h \ b
0000054


I am facing a small problem. I have a struct, which has a vector. Note that the vector is dynamic per every iteration. Now, in a particular iteration, how do I store the struct which contains a vector of size n to a binary file?

Also, when retrieving, assume that I know how the size of the vector, how to I retrieve from the binary file, the struct variable containing the vector of all the stored elements?

I am able to store something to the binary file (as I can see the size increasing when writing), but when I am trying to retrieve back the elements, I am getting size of vector to be zero.

Unfortunately, I have to achieve this using the standard STL and not use any third-party libraries.

解决方案

You should have a look at Boost Serialization.

If you can't use 3rd party libraries, you must know that C++ doesn't support serialization directly. This means you'll have to do it yourself.

This article shows a nice way of serializing a custom object to the disk and retrieving it back. And this tutorial shows you how to get started right now with fstream.

This is my attempt:

EDIT: since the OP asked how to store/retrieve more than record I decided to updated the original code.

So, what changed? Now there's an array student_t apprentice[3]; to store information of 3 students. The entire array is serialized to the disk and then it's all loaded back to the RAM where reading/searching for specific records is possible. Note that this is a very very small file (84 bytes). I do not suggest this approach when searching records on huge files.

#include <fstream>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;


typedef struct student
{
    char name[10];
    int age;
    vector<int> grades;
}student_t;

int main()
{
    student_t apprentice[3];  
    strcpy(apprentice[0].name, "john");
    apprentice[0].age = 21;
    apprentice[0].grades.push_back(1);
    apprentice[0].grades.push_back(3);
    apprentice[0].grades.push_back(5);    

    strcpy(apprentice[1].name, "jerry");
    apprentice[1].age = 22;
    apprentice[1].grades.push_back(2);
    apprentice[1].grades.push_back(4);
    apprentice[1].grades.push_back(6);

    strcpy(apprentice[2].name, "jimmy");
    apprentice[2].age = 23;
    apprentice[2].grades.push_back(8);
    apprentice[2].grades.push_back(9);
    apprentice[2].grades.push_back(10);

    // Serializing struct to student.data
    ofstream output_file("students.data", ios::binary);
    output_file.write((char*)&apprentice, sizeof(apprentice));
    output_file.close();

    // Reading from it
    ifstream input_file("students.data", ios::binary);
    student_t master[3];
    input_file.read((char*)&master, sizeof(master));         

    for (size_t idx = 0; idx < 3; idx++)
    {
        // If you wanted to search for specific records, 
        // you should do it here! if (idx == 2) ...

        cout << "Record #" << idx << endl;
        cout << "Name: " << master[idx].name << endl;
        cout << "Age: " << master[idx].age << endl;
        cout << "Grades: " << endl;
        for (size_t i = 0; i < master[idx].grades.size(); i++)
           cout << master[idx].grades[i] << " ";
        cout << endl << endl;
    }

    return 0;
}

Outputs:

Record #0
Name: john
Age: 21
Grades: 
1 3 5 

Record #1
Name: jerry
Age: 22
Grades: 
2 4 6 

Record #2
Name: jimmy
Age: 23
Grades: 
8 9 10

Dump of the binary file:

$ hexdump -c students.data 
0000000   j   o   h   n  \0 237   {  \0   �   �   {   � 025  \0  \0  \0
0000010   (   �   �  \b   4   �   �  \b   8   �   �  \b   j   e   r   r
0000020   y  \0   �  \0   �   �   |  \0 026  \0  \0  \0   @   �   �  \b
0000030   L   �   �  \b   P   �   �  \b   j   i   m   m   y  \0  \0  \0
0000040   �   6   �  \0 027  \0  \0  \0   X   �   �  \b   d   �   �  \b
0000050   h   �   �  \b                                                
0000054

这篇关于如何在二进制文件中读/写结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆