2011-05-27 83 views
2

您好, 我想存儲二進制一個std::vector<std::vector<int> >對象MATRIX在文件中。二進制讀/寫任意的std ::矢量<性病::矢量<int>>在C++

out.write((char*)&MATRIX, sizeof(MATRIX)); 

問題是,只有列維度是固定的。行維度更改。 如果我從二進制文件中讀取對象,僅僅知道尺寸是不夠的,不是嗎?所以,初始化例如的第二矩陣與

std::vector<std::vector<int> > MATRIX2; 
for (int i=0;i<column_dim;i++) MATRIX2.push_back (vector<int> (0)); 
ifstream in(cstr, ios::in | ios::binary); 

和讀取對象數據與

ifstream in(cstr, ios::in | ios::binary);  
in.read((char*)& MATRIX2, fSize); 

是沒有意義的,因爲編譯器不具有關於所保存的數據的結構的線索。 我的問題: 解決這個問題比第二個文件中保存矩陣結構(關於行尺寸的所有信息)有什麼更好的解決方法,讀取它並創建一個MATRIX2和適當的結構,然後用

ifstream in(cstr, ios::in | ios::binary);  
in.read((char*)&nn_H_test, fSize); 

+2

是給定的文件格式?如果不是,也許你想看看http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/index.html。這應該會讓你很容易存儲和加載int的矩陣。 – mkaes 2011-05-27 12:44:45

+0

擴展我在http://stackoverflow.com/questions/3438132/serialise-and-deserialise-vector-in-binary/3438541#3438541中建議的協議,在每個存儲矩陣前添加一個size_t來指定第一維。 – bobah 2011-05-27 12:46:56

+3

哎喲,你是否試圖在文件上做一個原始的'std :: vector'轉儲?這將*永遠不會*工作,讀回來你會得到一個完全混亂的狀態的對象(唯一正確的事情可能是矢量大小,但指向元素的內部指針將是無效的)。你需要正確的序列化。 – 2011-05-27 12:52:35

回答

3

我會給你一個關於如何使用boost來做到這一點的簡短例子。

#include <iostream> 
#include <fstream> 
#include <boost/serialization/serialization.hpp> 
#include <boost/serialization/vector.hpp> 
#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 

std::vector<std::vector<int > > g_matrix; 
int main(int argc, char* argv[]) 
{ 
    // fill the vector 
    std::ofstream ofs("c:\\dump"); 
    boost::archive::text_oarchive to(ofs); 
    to << g_matrix; 

    g_matrix.clear(); 
    std::ifstream ifs("c:\\dump"); 
    boost::archive::text_iarchive infs(ifs); 
    infs >> g_matrix; 
    // check your vector. It should be the same 
} 

如果您需要它更具人性化可讀性,您還可以嘗試從boost中提取xml。
一如既往不要重新發明輪子。

+1

......除非是爲了學習的目的! – fouronnes 2011-05-27 13:25:43

0

對於非常簡單的事情,爲什麼不只是在指定行列大小的矩陣輸出之前放置標題值?簡單的例子:

4,2 //#rows, #columns 
0 1 
2 0 
2 3 
4 5 

現在,當你在矩陣中讀取數據時,首先讀入數據頭信息,然後讀入矩陣數據。

如果你想矩陣是可序列化的,你應該看看矩陣結構的序列化範例。詳細瞭解C++ FAQ中的序列化。

+0

謝謝,是的,這也是我想到的第一件事,但它有一個缺點:我的一些算法已經使用這個矩陣,我不得不重寫它們 - 不幸的是,這會導致更多的工作,添加一個額外的文件。 – 2011-05-27 12:56:46

+0

如果這是一個問題,那麼序列化可能是您的解決方案。這樣它就全部包含在矩陣中。 – nathan 2011-05-27 13:16:50

2

ios :: binary是almost certainly NOT going to have the result you think it will have - 它隻影響行結束翻譯。其次,如果你想在閱讀時恢復結構,你不會逃避必須存儲內部向量的個別長度。將一個原始的std :: vector從一個流直接恢復到一個新的std :: vector中,就像你現在要做的一樣,不會有效。

然而,結構化的恢復不需要困難,只需存儲值的數量,然後存儲每個內部向量的所有值。然後,您的讀取例程可以安全地讀取第一個值,然後讀取N個下一個值,並假設之後的第一個值是下一行值的數目。

+0

感謝您的評論。對你的第一個評論:你會建議什麼? – 2011-05-27 13:08:13

+0

如果要將矢量存儲爲真正的「二進制」數據(例如,在磁盤上使用4個字節來存儲4個字節的整數),則應考慮使用流讀取和寫入來編寫自定義二進制文件流。 – 2011-05-27 13:35:41

相關問題