2012-04-08 3 views
0

Я работаю над проблемой, и я не уверен, правильно ли я делаю это, или если у меня вообще есть правильный подход. Мой код, до сих пор, просто дает мне segfaults.C++ - чтение динамически выделенных векторов из двоичного файла

У меня есть простая небольшая программа написания квитанций, чтобы практиковать некоторые концепции C++, один из которых является файлом ввода-вывода в двоичном формате. У меня есть несколько массивов, содержащих данные (один из которых содержит строки типа услуги, а другой - соответствующие двойные затраты). У меня есть небольшое меню, и запись в двоичной части идет хорошо. Тем не менее, я не уверен, как читать их обратно из файла.

В настоящее время я использую структуру для хранения различных членов данных (имя клиента, общие расходы и т. Д.), И я хочу написать все сервисы, которые они выбрали, вместе с их соответствующими ценами, в файл, а затем быть в состоянии прочитать их назад. Они в настоящее время хранятся в векторах в структуре.

Я думаю, что я понимаю, как читать/записывать строки в/из двоичного файла (записать длину строки, затем данные, затем прочитать длину назад, а затем прочитать, что много байтов в строку). Но как это сделать с помощью вектора? Я понимаю, как это можно сделать, например, с вектором элементов фиксированного размера (т. Е. Ints), но как насчет вектора строк? В этом случае члены не имеют заданного размера, поэтому я не уверен, как их читать.

Возможно ли это? Если бы кто-нибудь мог указать мне в правильном направлении, это было бы очень полезно. Был аналогичный форум, размещенный год назад, но это не очень помогло мне.

tl; dr - Как я могу прочитать вектор переменной длины строк переменной длины из двоичного файла?

+0

Мы должны увидеть код, чтобы быть в состоянии помочь вам – crazyjul

+0

См Повысьте Сериализацию Mark

+0

Http: //stackoverflow.com/questions/234724/how-to-serialize-in-c – keety

ответ

1

перефразировать:

> Как прочитать длину назад, а затем прочитать, что количество байтов в строку с вектором?

Одна строки в то время:

// Untested 
std::vector<std::string> ReadSomeStrings(std::istream& inFile, size_t howMany) { 
    std::vector<std::string> result; 
    for(int i = 0; i < howMany; ++i) { 
    std::size_t len; 
    is.read(&len, sizeof len); 
    std::string s(len, '\0'); 
    is.read(&s[0], s.size()); 
    result.push_back(s); 
    } 
    return result; 
} 
+0

Gotcha. Мне пришло в голову, что я должен это сделать. Думаю, я сохраню еще один вектор, который содержит длины всех строк. Благодарю. – nik

1

Вам необходимо упаковать или инкапсулировать ваши данные в объекты и сериализовать их, как указал Марк, используя http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html. Здесь вы можете найти примеры и подробную помощь. Ищите очень простой случай. :)

Редактировать: Я сделал для вас быстрый и грязный пример. Наслаждаться. (Извиняюсь за форматирование.)

#include <cstddef> // NULL 
#include <iomanip> 
#include <iostream> 
#include <fstream> 
#include <iterator> 

#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 
#include <boost/serialization/base_object.hpp> 
#include <boost/serialization/utility.hpp> 
#include <boost/serialization/assume_abstract.hpp> 
#include <boost/serialization/string.hpp> 
#include <boost/serialization/vector.hpp> 

class family_names 
{ 
    friend class boost::serialization::access; 
    std::vector<std::string> m_names; 
    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) 
    { 
    ar & m_names; 
    } 

    friend std::ostream & operator<<(std::ostream &os, const family_names& fn); 

    public: 
family_names(const std::vector<std::string>& names) 
    : m_names(names) 
{} 

family_names() {} 
    }; 

    std::ostream & operator<<(std::ostream &os, const family_names& fn) 
    { 
std::ostream_iterator<std::string> out_it (std::cout,", "); 
std::copy(fn.m_names.begin(), fn.m_names.end(), out_it); 
return os; 
    } 

    void save(const family_names &s, const char * filename){ 
// make an archive 
std::ofstream ofs(filename); 
boost::archive::text_oarchive oa(ofs); 
oa << s; 
    } 

    void restore(family_names &s, const char * filename) 
    { 
// open the archive 
std::ifstream ifs(filename); 
boost::archive::text_iarchive ia(ifs); 

// restore the family names from the archive 
ia >> s; 
    } 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 

std::vector<std::string> vec_names; 
vec_names.push_back("Jason"); 
vec_names.push_back("Mark"); 
vec_names.push_back("Ludmilla"); 


family_names names(vec_names); 
std::string filename = "c:\\Dev\\demofile.txt"; 

std::cout << names << std::endl; 
save(names, filename.c_str()); 

family_names names_back; 
restore(names_back, filename.c_str()); 
std::cout << names_back << std::endl; 

return 0; 
    } 
+0

Прохладный. Спасибо. Я ничего не сделал с повышением, но мне нужно будет это проверить. – nik

+0

Добро пожаловать. – ervinbosenbacher

0

Я предполагаю использовать >> и < < операторов, я рекомендую вам попробовать это с ofstream :: писать и ifstream :: читать бинарную манипуляцию.

Смежные вопросы