0

我有一个结构

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

我正在将其内容写入二进制文件。

我在不同的时间写作,并且在文件中有许多从这个结构写入的数据。

现在,我想将二进制文件中的所有数据读取到结构中。我不确定如何(动态地)为结构分配内存,以便结构可以容纳结构上的所有数据。

你能帮我解决这个问题吗?

代码:

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

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;

    input_file.seekg (0, ios::end);
    cout << input_file.tellg();

    std::vector<student_t> s;

    // input_file.read((char*)s, sizeof(s)); - dint work

    /*input_file >> std::noskipws;
    std::copy(istream_iterator(input_file), istream_iterator(), std::back_inserter(s));*/

    while(input_file >> master) // throws error
    {
        s.push_back(master);
    }
    return 0;
}
4

3 回答 3

3

您应该使用 avector<student_t>而不是旧式数组。它将处理动态分配(用于添加项目),您可以使用该方法push_back()获取其大小。size()

编辑: 对于文件读取,您可以执行以下操作:

ifstream myfile;
myfile.open(file_name);
if (myfile.is_open()) {
    while (myfile) {
        string s;
        getline(myfile, s);
        // Do something with the line
        // Push information into students vector
    }
}

不要忘记添加二进制选项。

对于结构name内部student_t,将其声明为string. 这样,您就不必使用strcpy等,您只需键入mystudent.name = "jimmy"

于 2012-10-19T22:19:38.273 回答
1

您需要为此发明一种文件格式。在文件的开头,您将存储一个所谓的“标题”,其中包含有关其中包含的数据的信息。例如:

2 13 <DATA> 8 <DATA>

第一个数字 (2) 给出了存储在文件中的结构的数量。然后是数据块。每个数据块都以一个指定grades向量大小的数字开头(第一个结构为 13,第二个结构为 8)。

在这种情况下,您从文件的开头读取一个 int。现在您知道该文件中保存了 2 个结构。然后,您阅读下一个 int,在本例中为 13。这告诉您您需要一个容量为 13 的向量。您可以创建一个,然后读取所有值。您将知道何时停止,因为您知道此结构中有多少数据:10 个字符(姓名)、1 个整数(年龄)、13 个整数(等级)。阅读完所有内容后,您就知道下一个 int 将成为文件中下一个结构的一部分。它将是数字 8,它告诉您下一个结构需要一个容量为 8 的向量。

等等,等等,直到你读完所有内容。

请注意,这种二进制文件 I/O 方法不可移植。有两个原因。首先,int 的大小在平台之间可能不同。其次,int(和其他大于单个字节的数据)以二进制形式存储的方式也可能不同,即使它们具有相同的大小(有关解释,请参见http://en.wikipedia.org/wiki/Endianness .) 但是,如果您不希望您的程序和它生成的文件无论如何都是可移植的,那么我上面描述的方法就足够了。

于 2012-10-19T22:44:44.843 回答
0

最直接的方法是将向量解包,这样您写入文件的不是向量,而是一个整数数组以及数组中的整数数。

因此,第一遍将是编写具有标准、不变结构的第一部分,然后是一个数字,表示将跟随的整数数量,然后最后遍历将整数写入文件的向量。

然后,当您读取文件时,您将使用空向量创建结构,读取结构化且不变的第一部分到结构中,然后读取要放置在向量中的整数数,然后读取整数数从文件中。当您从文件中读取整数时,您会将它们添加到结构中的向量中。

于 2012-10-19T22:09:33.750 回答