2013-08-01 86 views
3

我要救這個結構以後加載:寫在文件C讀取結構的三維矢量++

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

我不明白你想要做什麼。 .. –

+0

我填寫'relationTable'並想將其保存在文件或數據庫中以便稍後使用它! –

+0

你可以用'json'格式序列化你的對象嗎? –

回答

6

這不是很清楚什麼是你的關係表。 如果你想你的結構保存到一個文件中,更簡單的方法是使用的boost ::系列化 見: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'

+0

你能解釋一下嗎? –

+0

+1顯示我的建議 – sehe

+1

我添加了一個完整的工作示例以方便 – sehe

2

我建議

  • 升壓PropertyTree(用於XML,JSON)
  • 升壓序列化(二進制,XML,文本)
  • libjsoncpp(甚至this

還是.....你好LD使用升壓精神

你可以使用一個噶生成序列化塊:

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

它打印單Blockoss

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"; 
    } 
}