2014-05-16 39 views
1

我想將我的數組結構寫入二進制文件。問題在C++中讀寫二進制文件中的結構數組

我的結構

typedef struct student{ 
    char name[15]; 
    vector<int> grade; 
}arr_stu; 

我能寫和讀回我的數據,如果我寫,並在相同的程序讀取;但如果我只爲讀取數據創建另一個程序並放入二進制文件,則它不起作用,因爲矢量等級爲空。

size = 0; 
unable to read from memory 

程序寫入陣列結構到文件

int main() 
{ 
arr_stu stu[100]; 

for (size_t i = 0; i < 100; i++) 
{ 
    strcpy(stu[i].name, randomName()); 
    for (size_t j = 0; j < 10; j++) 
    { 
     stu[i].grade.push_back(randomGrade()); 
    } 
} 

ofstream outbal("class", ios::out | ios::binary); 
if (!outbal) { 
    cout << "Cannot open file.\n"; 
    return 1; 
} 

outbal.write((char *)&stu, sizeof(stu)); 
outbal.close(); 
} 

程序讀取陣列結構到文件

int main(){ 

    feature_struc stu[100]; 

    ifstream inbal("class", ios::in | ios::binary); 
if (!inbal) { 
    cout << "Cannot open file.\n"; 
    return 1; 
} 

inbal.read((char *)&stu, sizeof(stu)); 

for (size_t idx = 0; idx < 100; idx++) 
{ 
    cout << "Name : " << stu[idx].name << endl; 
    for (size_t index = 0; index < 10; index++) 
    { 
     cout << endl << "test: " << stu[idx].grade[index] << endl; 
    } 
} 
inbal.close(); 
return 0; 
} 

對於我來說,好像使用矢量的姿問題, 如果我們在一個程序中合併這兩個程序,它的工作很好的原因是我t因爲矢量被保存在內存中,所以它仍然可以訪問。

有什麼建議嗎?

+0

你不需要'typedef結構...',你也應該使用更多的'標準::矢量'以及'std :: string'而不是數組和C字符串。 – crashmstr

+0

你必須爲此使用二進制文件?如果你想保持二進制樣式,你不能使用'XML','YAML','JSON'甚至'sqlite'嗎? –

回答

4

你不能像這樣序列化一個向量。函數writeread函數直接訪問給定地址處的內存。由於vector是一個複雜的類類型,其數據內容只有部分按順序存儲在其基址中。其他部分(堆分配內存等)位於其他地方。最簡單的解決方案是將矢量的長度寫入文件,然後寫入每個值。你必須遍歷向量元素來完成。

+0

是否有任何解決方案不會遍歷所有向量元素,以防我們擁有大量內容? – sayvortana

+0

C++ 11中的向量實現提供了一個'data'成員函數,它可以直接返回一個指向分配內存的指針,用於序列化內容。以前的標準不提供這個功能,所以你不能避免迭代內容。 – jasal

+1

您可能還想看看[boost :: serialization庫](http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html),它實現了泛型模式序列化對象 – jasal

1

outbal.write((char *)&stu, sizeof(stu));

sizeof是一個編譯時間常數。換句話說,它永遠不會改變。如果矢量包含1,10,1000或1,000,000個項目,則您將相同數量的字節寫入文件。所以這種寫入文件的方式是完全錯誤的。

由於vector是非POD類型,因此您正在編寫的結構爲non-POD。這意味着您不能將其視爲可從中複製或複製到的一組字節。如果您需要進一步證明,請打開您在任何編輯器中創建的文件。你能看到該文件中的矢量數據嗎?你會看到的很可能是胡言亂語。

將數據寫入到文件中,你必須正確地序列化數據,這意味着你必須寫數據到一個文件,而不是struct本身。您以某種方式編寫數據,以便在讀取數據時可以重新創建結構。最終,這意味着您必須

  1. 將名稱寫入文件,並可能包含名稱所包含的字節數。
  2. 寫入向量中的項目數
  3. 將每個向量項寫入文件。

如果不是這樣,那麼一些方法,你可以清楚地從文件中找出名稱和矢量數據,使你的代碼讀取數據正確地解析文件並重新創建結構。

+0

不能寫入莢這種方式,或者說,並期望能夠反覆閱讀。 –

0

二進制文件的格式是什麼?基本上,你必須定義格式 ,然後將每個元素轉換成 這個格式。您永遠不能將內部 表示的位轉儲到磁盤,並希望能夠讀取它。 (事實上,你需要一個reinterpret_cast打電話給你的對象 ostream::write應該告訴你的東西。)

相關問題