двоичное чтение / запись произвольный std :: vectorв с ++ - PullRequest
2 голосов
/ 27 мая 2011

Привет , я хотел бы сохранить двоичный объект std::vector<std::vector<int> > MATRIX в файле.

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

?

Ответы [ 3 ]

3 голосов
/ 27 мая 2011

Я приведу краткий пример того, как сделать это с 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
}

Если вам нужно, чтобы он был более читабельным, вы также можете попробовать xml из boost.
Как всегда, не изобретай велосипед.

2 голосов
/ 27 мая 2011

ios :: binary = почти наверняка НЕ ​​даст результата, который, как вы думаете, будет иметь - это влияет только на перевод конца строки.

Во-вторых, вы не избежите необходимости хранить отдельные длины внутренних векторов, если хотите восстановить структуру после чтения. Восстановление необработанного std :: vector из потока непосредственно в новый std :: vector, как вы пытаетесь сейчас, не сработает.

Структурное восстановление, однако, не должно быть сложным, просто сохраните количество значений, а затем все значения для каждого внутреннего вектора. Затем ваша процедура чтения может безопасно прочитать первое значение, затем прочитать N следующих значений и принять первое значение после него как число значений в следующей строке.

0 голосов
/ 27 мая 2011

Для чего-то чрезвычайно простого, почему бы просто не поместить значение заголовка перед выводом вашей матрицы, которое определяет размер столбца строки? Тривиальный пример:

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

Теперь, когда вы читаете в матрице, читайте в заголовке информацию, а затем данные матрицы.

Если вы хотите, чтобы матрица была сериализуемой, вам следует взглянуть на парадигму сериализации для вашей структуры матрицы. Подробнее о сериализации читайте в C ++ FAQ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...