2017-03-09 101 views
0

這是我有:如何將矢量保存到二進制文件?

#include <vector> 
#include <fstream> 
#include <iostream> 
using namespace std; 

void saveVector(vector<ObjectName*>); 
vector<ObjectName*> readVector(); 

int main(){ 
    vector<ObjectName*> objects; 


    int option; 
    cin >> option; 

    switch(option){ 
     case 1:{ 
     //read vector 
      for(int i =0; i < readVector().size(); i++){ 
       objects.push_back(readVector()[i]); 
      } 
      break; 
     } 
     case 2:{ 
      //save vector 
      objects.push_back(new ObjectName()); 
      saveVector(); 
      break;  
     }   



    return 0; 
} 

void saveVector(vector<ObjectName*> objects){ 
    ofstream fout("./Binary/ObjectsData.bin", ios::out | ios::binary); 
    int size1 = objects.size(); 
    fout.write((char*)&size1, sizeof(size1)); 
    fout.write((char*)objects.data(), size1 * sizeof(int)); 
    fout.flush(); 
    fout.close(); 
} 


vector<ObjectName*> readVector(){ 
    vector<ObjectName*> list2; 

    ifstream is("./Binary/ObjectsData.bin", ios::binary); 
    int size2; 
    is.read((char*)&size2, 4); 
    list2.resize(size2); 

    is.read((char*)&list2[0], size2 * sizeof(list2)); 
    is.close(); 

    return list2; 

} 

對象名只是爲任何類型的對象的名稱。

我在做什麼錯?如果我得到「對象」矢量大小並將其與「readVector()」矢量大小(第一次執行程序並保存矢量之後)進行比較,則表明它們具有相同的大小,但如果我嘗試添加「對象」向量的另一個對象,我得到「分段錯誤(核心轉儲)」。有沒有更好的方式來保存和讀取對象並將它們添加回矢量?

+0

添加'#include '可能會有所幫助。 – user4581301

+2

保存指向二進制文件的指針沒有什麼意義。 –

+0

什麼是'ObjectName'?和'ObjectType'? – user4581301

回答

5

恐怕你有lot在這裏的問題,最終你只需要回到一個很好的C++教程,只是學習語言。在這裏,你已經遠離目前對語言的理解。

但是,一個很大的問題是,您將指針保存到您的對象,而不是對象本身。您不能保存先前執行的程序的指針,然後在後續的程序中使用它們。指針只在分配它們指向的內存之間有效,以及當它們明確地被delete或程序結束時。

你需要做的是單獨保存每個對象—指向的對象,而不是指針本身—然後,一次一個,創建對象,從您的文件中讀取它們,並添加指針向他們傳播。或者,你可以將對象直接存儲在向量中,而不僅僅是指向它們的指針。

但是,無論哪種方式,如果您的對象不是普通舊數據,它們都不會起作用,因爲否則它們會在您的對象中包含無法保存的類似vtables的內容。在這種情況下,您需要更復雜的序列化方法,而不僅僅是將內存轉出到磁盤並將其讀回。

+0

是啊,我剛剛重寫了我有錯誤的代碼(我用西班牙語中的變量名)。我的意思是保存包含指向對象的向量的元素,所以我知道我必須對它們進行解引用,但那只是當我想將對象一個接一個存儲在二進制文件中。但我想要做的是將包含指向對象的指針的向量保存爲二進制文件,這是一個壞主意嗎? –

+1

問題是,矢量不包含對象,它包含指向對象的指針。通過保存矢量內容的原始內存,您保存的只是指針,而不是它們指向的對象。 如果你想用一次內存轉儲保存所有的對象,你需要使用'std :: vector ',它將對象本身存儲在向量中,而不是'std :: vector '它只存儲指向對象的指針。否則,您必須通過取消引用來一次保存一個對象。 –

+0

好吧,我會嘗試並保存對象,而不是指針 –

0

首先編寫一個序列化單個對象的函數。這可能是的<<運營商。然後,編寫一個for循環或std::for_each調用,該調用在vector上迭代並序列化每個對象。將對象本身存儲在向量中,而不是指向它們的指針(或者如果以後要存儲指針或智能指針,則可以在for循環中取消引用它們)。

簡單的例子,不是一個完整的回答你的問題:

#include <cstdlib> 
#include <iostream> 
#include <vector> 

using std::cout; 

int main(void) 
{ 
    std::vector<int> v = {1,2,3}; 

    for (const int &i : v) 
    cout << i << std::endl; 

    return EXIT_SUCCESS; 
} 

您可以std::ostream::write()寫入二進制數據,而不是字符串數據。如果你真的關心跨平臺兼容性,你首先會轉換成指定佈局和字節順序的標準格式,但你可能不需要,所以在地址reinterpret_cast<const char*>(&x)處寫sizeof(x)字節應該足夠好。這隻適用於普通舊數據類型。

+0

感謝您的幫助 –

相關問題