-->

序列化的std ::列表为JSON与升压ptree中(Serializing std::list i

2019-10-22 08:35发布

好了,所以我敲我的这一头,过去几天,但我仍无法得到它的权利。 我有一个std ::列表容器,我想它序列化到JSON字符串,这样我可以在发送网络。

注:我编译使用下面我的代码:

g++ -std=c++11 -o main main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization

我把帮助这个和这个

下面是我的DBAccess1.h文件。

#ifndef DBAccess1_HH  
#define DBAccess1_HH

#include <list> // I have deleted some header for sake of readability
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

//================================//   
struct SiteCode
{
      int siteID;
      int siteCode;
};

inline ostream& operator<< (ostream &out, SiteCode &site)
{
    out << "(" << site.siteID << "," << site.siteCode << ")";
    return out;
}
//================================//

class sqliteDB {
    list<SiteCode> Site_Code_list;
public:
    list<SiteCode> GET_ALL_Site_Code();
    void printList();
};
#endif**

下面是所有功能都定义DBAccess11.cpp文件

#include <list> // I have deleted some header for sake of readability
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/list.hpp>
#include "DBAccess1.h"

using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

list<SiteCode> sqliteDB::GET_ALL_Site_Code()
{
        sqlite3 *db;
        const char *sql;
        sqlite3_stmt * stmt;

        int rc = sqlite3_open("/path/to/database.db", &db);
        sql = "SELECT * FROM SiteCode;";       
        rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);

    while(sqlite3_step(stmt)==SQLITE_ROW) {

            int A  = sqlite3_column_int(stmt, 0);
            int B = sqlite3_column_int(stmt, 1);

            SiteCode info;
            info.siteID = A;
            info.siteCode = B;              

            cout<<"Preparing to push data into List"<<endl;
            Site_Code_list.push_back(info);
            cout<<"Data was pushed successfully"<<endl;

            ptree pt;
            for (auto& entry: list<SiteCode> Site_Code_list)  //<< ERROR LINE80
            pt.put(entry.siteID, entry.siteCode);
            std::ostringstream buf; 
            write_json (buf, pt, false); 
            cout<< buf.str() << endl;
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return Site_Code_list;
}
//====================================================//
void sqliteDB::printList()
{
     int s = Site_Code_list.size();
     cout << "The size of List is :" << s << endl;
     for( list<SiteCode> :: iterator it = Site_Code_list.begin(); it !=  Site_Code_list.end(); it++)     
     cout << *it << " ";
}

下面是main.cpp中

#include <list> // I have deleted some header for sake of readability
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

int main()
{
    sqliteDB object1;
    object1.GET_ALL_Site_Code();
    object1.printList();
    cout << "\n\nAll the statement were executed properly\n\n";
    return 0;
}

我得到的错误是如下:

DBAccess11.cpp: In member function ‘std::list<SiteCode> sqliteDB::GET_ALL_Site_Code()’:
DBAccess11.cpp:80:38: error: expected primary-expression before ‘Site_Code_list’
 for (auto& entry: list<SiteCode> Site_Code_list)
                                  ^
DBAccess11.cpp:80:38: error: expected ‘)’ before ‘Site_Code_list’
DBAccess11.cpp:80:52: error: expected ‘;’ before ‘)’ token
 for (auto& entry: list<SiteCode> Site_Code_list)
                                                ^

我的问题:

(1)这是使用升压到的std ::列表转换成JSON的正确方法? NO时应该怎样做呢? (注意:我只能用升压并没有其他库)

(2)如果我的做法是正确的话,我应作出哪些改变来纠正呢?

Answer 1:

树中的路径始终为字符串。 编译器会告诉你,这在消息的剩余部分。 可以说是文档是一个更可读的源:

双方key_typedata_type是可配置的,但通常会std::string 这里

所述self_type & put(const path_type & path, const Type & value, Translator tr);

所以修复的本质是

pt.put(std::to_string(entry.id), entry.code);

我有一点点扯到清理代码,所以这里有云:

自包含的样本

// FILE: some header
#include <ostream>

struct SiteCode {
    int id;
    int code;

    SiteCode(int id, int code) : id(id), code(code)
    { }

    friend inline std::ostream &operator<<(std::ostream &out, SiteCode const& site) {
        return out << "(" << site.id << "," << site.code << ")";
    }
};

#include <list> // I have deleted some header for sake of readability

// FILE: sqliteDB header
class sqliteDB {
    using Records = std::list<SiteCode>;
    Records _records;

  public:
    void load();
    Records const& get() const { return _records; }
    void printList() const;
    void writeJson(std::ostream& os) const;
};

// FILE: some sqlpp.hpp utility header (inline implementations only)
#include <memory>
#include <sqlite3.h>

namespace sqlpp {
    using database  = std::shared_ptr<::sqlite3>;

    void perror(int rc) {
        if (rc != SQLITE_OK) throw std::runtime_error(::sqlite3_errstr(rc));
    }

    struct statement {
        static statement prepare(database db, std::string const& sql) {
            ::sqlite3_stmt* stmt = nullptr;
            perror(::sqlite3_prepare_v2(db.get(), sql.c_str(), -1, &stmt, 0));

            return { handle(stmt, ::sqlite3_finalize), db };
        }

        int step()            { return ::sqlite3_step(_stmt.get()); }
        int column_int(int c) { return ::sqlite3_column_int(_stmt.get(), c); }
      private:
        using handle = std::shared_ptr<::sqlite3_stmt>;
        database _db; // keeping it around for the lifetime of _stmt
        handle _stmt;

        statement(handle&& h, database& db) : _db(db), _stmt(std::move(h)) { }
    };

    database open(char const* path) {
        ::sqlite3* db = nullptr;
        perror(::sqlite3_open(path, &db));

        return database(db, ::sqlite3_close);
    }

    statement prepare(database db, std::string const& sql) {
        return statement::prepare(db, sql);
    }
}

// FILE: sqliteDB implementation file
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

void sqliteDB::load() {
    using namespace sqlpp;

    auto stmt = prepare(open("/tmp/database.db"), "SELECT ID, CODE FROM SiteCode;");

    while (stmt.step() == SQLITE_ROW)         
        _records.emplace_back(stmt.column_int(0), stmt.column_int(1));
}

void sqliteDB::writeJson(std::ostream& os) const {
    using namespace boost::property_tree;
    ptree pt;

    for (auto &entry : _records)
        pt.put(std::to_string(entry.id), entry.code);

    write_json(os, pt, false);
}

// FILE: main program
template <typename List>
static void printList(List const& list) {
    int s = list.size();
    std::cout << "The number of Records is: " << s << "\n";

    for (auto& r : list) std::cout << r << " ";
}

void dump(sqliteDB const& db) {
    printList(db.get());
    std::cout << "\n==============[ AS JSON ]===============\n";
    db.writeJson(std::cout);
}

int main() { 
    sqliteDB db;

    std::cout << "before loading: \n";
    dump(db);

    std::cout << "after loading: \n";
    db.load();
    dump(db);
}

只是编译为g++ -std=c++11 -g -Wall -Wextra -pedantic main.cpp -lsqlite3并获得:

sehe@desktop:/tmp$ sqlite3 database.db <<< "create table SiteCode (id int primary key, code int);"
sehe@desktop:/tmp$ for a in {1..10}; do echo "insert into SiteCode(ID,CODE) VALUES($a, $RANDOM);"; done | sqlite3 database.db 
sehe@desktop:/tmp$ ./test

产量

before loading: 
The number of Records is: 0

==============[ AS JSON ]===============
{}
after loading: 
The number of Records is: 10
(1,5591) (2,31578) (3,30641) (4,4850) (5,1628) (6,5133) (7,8798) (8,20601) (9,21213) (10,18222) 
==============[ AS JSON ]===============
{"1":"5591","2":"31578","3":"30641","4":"4850","5":"1628","6":"5133","7":"8798","8":"20601","9":"21213","10":"18222"}


Answer 2:

确定,所以对工作溶液上方提供由sehe。 我终于能够得到输出权。 我不得不修改自己的解决方案按我的需要。 这里的答案是按以下。 所有信用卡和感谢sehe。

下面是我的DBAccess1.h文件:

#ifndef DBAccess1_HH
#define DBAccess1_HH

#include <sqlite3.h>
#include <list>   
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

//=========================//
struct SiteCode
{
  int siteID;
  int siteCode;

    friend inline std::ostream &operator<<(std::ostream &out, SiteCode const& site) {
    return out << "(" << site.siteID << "," << site.siteCode << ")";
    }
};
//=========================//
class sqliteDB {

using Records = std::list<SiteCode>;
Records Site_Code_list;

public:

list<SiteCode> GET_ALL_Site_Code();
Records const& get() const { return Site_Code_list; }
void writeJson(std::ostream& os) const;
void printList() const;
};

#endif

下面是DBAccess11.cpp

#include <ostream>
#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include "DBAccess1.h"

using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

list<SiteCode> sqliteDB::GET_ALL_Site_Code()
{
        sqlite3 *db;
        const char *sql;
        sqlite3_stmt * stmt;

        int rc = sqlite3_open("/path.to/database.db", &db);

        sql = "SELECT * FROM SiteCode;";

        rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);

        while(sqlite3_step(stmt)==SQLITE_ROW) {

            int A  = sqlite3_column_int(stmt, 0);
            int B = sqlite3_column_int(stmt, 1);

            SiteCode info;
            info.siteID = A;
            info.siteCode = B;              

            cout<<"Preparing to push data into List"<<endl;
            Site_Code_list.push_back(info);
            cout<<"Data was pushed successfully"<<endl;
    }
    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return Site_Code_list;
}
//==============================================================//
void sqliteDB::writeJson(std::ostream& os) const
{
    using namespace boost::property_tree;
    ptree pt;

    for (auto &entry : Site_Code_list)
        pt.put(std::to_string(entry.siteID), entry.siteCode);

    write_json(os, pt, false);
}
//=========================================================//

下面是main.cpp中

#include <ostream>

#include <boost/serialization/list.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include "DBAccess1.h"

using namespace std ;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;

template <typename List>
static void printList(List const& list) {
    int s = list.size();
    std::cout << "The number of Records is: " << s << "\n";
    for (auto& r : list) std::cout << r << " ";
}

void dump(sqliteDB const& db) {
    printList(db.get());
    std::cout << "\n==============[ AS JSON ]===============\n";
    db.writeJson(std::cout);
}

int main()
{

    sqliteDB object1;

    std::cout << "before loading: \n";
    dump(object1);

    std::cout << "after loading: \n";
    object1.GET_ALL_Site_Code();
    dump(object1);

    return 0;
}

编译上述使用:

g++ -std=c++11 -o main main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization 

而下面的输出我得到:

before loading: 
The number of Records is: 0

==============[ AS JSON ]===============
{}
after loading: 
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
Preparing to push data into List
Data was pushed successfully
The number of Records is: 10
(7,786) (8,78) (9,785) (10,998) (11,656) (13,23) (14,7) (15,74) (16,954) (17,752) 
==============[ AS JSON ]===============
{"7":"786","8":"78","9":"785","10":"998","11":"656","13":"23","14":"7","15":"74","16":"954","17":"752"}


文章来源: Serializing std::list into json with boost ptree