我想保存这个结构并稍后加载它:
struct Block
{
vector<int> numbers;
map<int , char> bits;
map<string , string > states;
string off;
}relationTable[7][11][13];
除了使用多个for
循环外,有什么办法吗?
我使用此功能进行保存:
void saveData()
{
string location = "test.bin";
ofstream fs(location, std::ios::out | std::ios::binary | std::ios::app);
fs.write(reinterpret_cast<const char *>(relationTable), sizeof(relationTable));
fs.close();
}
这个用于加载:
void loadData()
{
string location = "test.bin";
Block array[64][96][2];
ifstream file (location, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
file.seekg (0, ios::beg);
file.read ((char*)&array, sizeof(array));
file.close();
}
...//some use of array
}
但它不起作用,因为它只保存指针!我该怎么办?
答案 0 :(得分:7)
目前还不是很清楚什么是关系表。 如果要将结构保存到文件中,更简单的方法是使用 boost :: serialization 见:How do you serialize an object in C++?
你可以这样做:
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, Block& b, const unsigned int version)
{
ar & b.numbers;
ar & b.bits;
ar & b.states;
ar & b.off;
}
void save_Block(const Block &b, const char * filename){
// make an archive
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << b;
}
}}
完全正常工作的示例程序:
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>
struct Block
{
typedef std::vector<int> Numbers;
typedef std::map<int, char> Bits;
typedef std::map<std::string, std::string> States;
Numbers numbers;
Bits bits;
States states;
std::string off;
};
namespace boost { namespace serialization {
template<class Archive>
void serialize(Archive & ar, Block& b, const unsigned int version)
{
ar & b.numbers;
ar & b.bits;
ar & b.states;
ar & b.off;
}
} }
void save_Block(const Block &b, const char * filename){
// make an archive
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << b;
}
int main()
{
save_Block(Block {
{ 1, -42 },
{ { 3, '0' }, { 17, '1' } },
{ { "disabled", "true" }, { "locked", "false" }, { "ui", "manual" } },
"something called 'off'"
},
"test.txt");
}
文件test.txt
将包含:
22 serialization::archive 10 0 0 2 0 1 -42 0 0 2 0 0 0 3 48 17 49 0 0 3 0 0 0 8 disabled 4 true 6 locked 5 false 2 ui 6 manual 22 something called 'off'
答案 1 :(得分:2)
我推荐
或.....你可以使用 提升精神
您可以使用Karma生成器序列化块:
template <typename It>
struct generator : karma::grammar<It, Block(), karma::space_type>
{
generator() : generator::base_type(start)
{
using namespace karma;
start = numbers << bits << states << off;
numbers = lit("numbers") << '{' << -(int_ % ',') << '}';
bits = lit("bits") << '{' << -(bit % ',') << '}';
states = lit("states") << '{' << -(state % ',') << '}';
off = lit("off") << string_;
bit = int_ << ':' << char_;
state = string_ << ':' << string_;
string_ = '"' << *('\\' << char_('"') | char_) << '"';
}
// ...
};
这用,例如:
static const generator<boost::spirit::ostream_iterator> gen;
std::ostringstream oss;
oss << karma::format_delimited(gen, karma::space,
Block {
{ 1, -42 },
{ { 3, '0' }, { 17, '1' } },
{ { "disabled", "true" }, { "locked", "false" }, { "ui", "manual" } },
"something called 'off'"
}) << "\n";
将单Block
打印到oss
:
numbers { 1 , -42 } bits { 3 : 0 , 17 : 1 } states { "disabled" : "true" , "locked" : "false" , "ui" : "manual" } off "something called 'off'"
然后你可以使用镜像语法解析它:
Block reparsed;
std::string const input = oss.str();
auto f(begin(input)), l(end(input));
assert(qi::phrase_parse(f,l,par,qi::space,reparsed));
查看完整的程序:
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
struct Block
{
typedef std::vector<int> Numbers;
typedef std::map<int, char> Bits;
typedef std::map<std::string, std::string> States;
Numbers numbers;
Bits bits;
States states;
std::string off;
};
BOOST_FUSION_ADAPT_STRUCT(Block,
(Block::Numbers, numbers)
(Block::Bits, bits)
(Block::States, states)
(std::string, off))
template <typename It, typename Skipper = qi::space_type>
struct parser : qi::grammar<It, Block(), Skipper>
{
parser() : parser::base_type(start)
{
using namespace qi;
start = numbers >> bits >> states >> off;
numbers = no_case ["numbers"] >> '{' >> -(int_ % ',') > '}';
bits = no_case ["bits" ] >> '{' >> -(bit % ',') > '}';
states = no_case ["states" ] >> '{' >> -(state % ',') > '}';
off = no_case ["off" ] >> string_;
bit = int_ >> ':' > char_;
state = string_ >> ':' > string_;
string_ = '"' >> *('\\' > char_ | ~char_('"')) > '"';
BOOST_SPIRIT_DEBUG_NODES((start)(numbers)(bits)(states)(off)(bit)(state)(string_));
}
private:
qi::rule<It, Block(), Skipper> start;
qi::rule<It, Block::Numbers(), Skipper> numbers;
qi::rule<It, Block::Bits(), Skipper> bits;
qi::rule<It, Block::States(), Skipper> states;
qi::rule<It, std::pair<int, char>(), Skipper> bit;
qi::rule<It, std::pair<std::string, std::string>(), Skipper> state;
qi::rule<It, std::string(), Skipper> off;
qi::rule<It, std::string()> string_;
};
template <typename It>
struct generator : karma::grammar<It, Block(), karma::space_type>
{
generator() : generator::base_type(start)
{
using namespace karma;
start = numbers << bits << states << off;
numbers = lit("numbers") << '{' << -(int_ % ',') << '}';
bits = lit("bits") << '{' << -(bit % ',') << '}';
states = lit("states") << '{' << -(state % ',') << '}';
off = lit("off") << string_;
bit = int_ << ':' << char_;
state = string_ << ':' << string_;
string_ = '"' << *('\\' << char_('"') | char_) << '"';
BOOST_SPIRIT_DEBUG_NODES((start)(numbers)(bits)(states)(off)(bit)(state)(string_));
}
private:
karma::rule<It, Block(), karma::space_type> start;
karma::rule<It, Block::Numbers(), karma::space_type> numbers;
karma::rule<It, Block::Bits(), karma::space_type> bits;
karma::rule<It, Block::States(), karma::space_type> states;
karma::rule<It, std::pair<int, char>(), karma::space_type> bit;
karma::rule<It, std::pair<std::string, std::string>(), karma::space_type> state;
karma::rule<It, std::string(), karma::space_type> off;
karma::rule<It, std::string()> string_;
};
int main()
{
typedef std::string::const_iterator It;
static const parser<It, qi::space_type> par;
static const generator<boost::spirit::ostream_iterator> gen;
Block reparsed;
{
std::ostringstream oss;
oss << karma::format_delimited(gen, karma::space,
Block {
{ 1, -42 },
{ { 3, '0' }, { 17, '1' } },
{ { "disabled", "true" }, { "locked", "false" }, { "ui", "manual" } },
"something called 'off'"
}) << "\n";
std::string const input = oss.str();
auto f(begin(input)), l(end(input));
assert(qi::phrase_parse(f,l,par,qi::space,reparsed));
// serialize and deserialize the whopping 3D collection of Blocks:
std::cout << karma::format_delimited(gen, karma::space, reparsed) << "\n";
}
}