簡體   English   中英

在C ++中從文件讀取時動態地將內存分配給結構

[英]dynamically allocating memory to struct when reading from file in C++

我有一個結構

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

您應該使用vector<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
    }
}

不要忘記也添加二進制選項。

對於您的student_t結構中的name ,將其聲明為string會容易得多。 這樣,您不必使用strcpy之類的東西,您只需鍵入mystudent.name = "jimmy"

最直接的方法是解包向量,以便您寫入文件的內容不是向量,而是一個整數數組以及該數組中整數的數量。

因此,第一步是編寫具有標准不變結構的第一部分,然后編寫一個數字,該數字表示將要遵循的整數的數量,然后最終遍歷將整數寫入文件的向量。

然后,當您讀取文件時,將使用空向量創建結構,讀取結構化且不變的結構的第一部分,然后讀取將要放置在向量中的int數,然后讀取該int數從文件中。 從文件讀取int時,會將它們添加到結構中的向量中。

您需要為此發明一種文件格式。 在文件的開頭,您將存儲一個所謂的“標題”,其中包含有關其中包含的數據的信息。 例如:

2 13 <DATA> 8 <DATA>

第一個數字(2)給出文件中存儲的結構數量。 然后是數據塊。 每個數據塊均以一個指定grades矢量大小的數字開頭(第一個結構為13,第二個結構為8)。

在這種情況下,您將從文件開頭讀取一個int。 現在您知道該文件中保存了2個結構。 然后,您讀取下一個int,在這種情況下為13。 這表明您需要一個容量為13的向量。可以創建一個向量,然后讀取所有值。 您將知道何時停止,因為您知道此結構中有多少數據:10個字符(名稱),1個整數(年齡),13個整數(等級)。 讀完所有內容之后,您便知道下一個int將成為文件中下一個struct的一部分。 它是數字8,它告訴您下一個結構需要一個容量為8的向量。

等等,直到您閱讀完所有內容。

請注意,這種二進制文件I / O方法不可移植。 有兩個原因。 首先,不同平台之間int的大小可能會有所不同。 其次,以二進制形式存儲int(以及其他大於單個字節的數據)的方式也可能有所不同,即使它們的大小相同(有關說明,請參見http://en.wikipedia.org/wiki/Endianness) 。)但是,如果您不打算將程序及其生成的文件移植為可移植的,那么上面介紹的方法就足夠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM