使用boost ptree将std :: list序列化为json [英] Serializing std::list into json with boost ptree
问题描述
好吧,所以我在最近几天碰到我的头,但我仍然无法得到它的权利。我有一个std :: list容器,我想将其序列化为JSON字符串,使我可以通过网络发送它。
注意:使用以下代码编译代码:
g ++ -std = c ++ 11 - 主main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization
以下是我的 DBAccess1.h 文件。
#ifndef DBAccess1_HH
# define DBAccess1_HH
#include< list> //我为了可读性删除了一些头
#include< boost / serialization / list.hpp>
#include< boost / property_tree / ptree.hpp>
#include< boost / property_tree / json_parser.hpp>
using namespace std;
使用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&运算符<< (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& //我为了可读性删除了一些头
#include< boost / property_tree / ptree.hpp>
#include< boost / property_tree / json_parser.hpp>
#include< boost / serialization / list.hpp>
#includeDBAccess1.h
使用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.siteID = A;
info.siteCode = B;
cout<<准备将数据推入列表<< endl;
Site_Code_list.push_back(info);
cout<<已成功推送数据<< 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<< List的大小是:< s<< endl;
for(list< SiteCode> :: iterator it = Site_Code_list.begin(); it!= Site_Code_list.end(); it ++)
cout< * it< ;
}
以下是 main.cpp
#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;
int main()
{
sqliteDB object1;
object1.GET_ALL_Site_Code();
object1.printList();
cout<< \\\
\\\
All语句已正确执行\\\
\\\
;
return 0;
}
我得到的错误如下:
DBAccess11.cpp:在成员函数'std :: list< SiteCode> sqliteDB :: GET_ALL_Site_Code()':
DBAccess11.cpp:80:38:错误:Site_Code_list之前的主表达式
(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)
^
/ p>
(1)这是否是使用boost将 std :: list转换成JSON 的正确方法?如果否,那么应该如何做呢?
(注意 - 我只能使用boost而没有其他库)
(2)如果我的方法是正确的,
树中的路径总是字符串。编译器会在消息的其余部分告诉你这一点。可以证明文档是一个更易读的来源:
两个
key_type
和data_type
是可配置的,但通常为std :: string
此处
b
$ b
self_type& put(const path_type& path,const Type& value,Translator tr);
因此修复的本质是
pt.put(std :: to_string(entry.id),entry.code );
我有一些侧面跟踪清理代码,所以这里:
自包含示例
header
#include< ostream>
struct SiteCode {
int id;
int code;
SiteCode(int id,int code):id(id),code(code)
{}
friend inline std :: ostream& <(std :: ostream& out,SiteCode const& site){
return out< (<< site.id<<,<< site.code<<);
}
};
#include< list> //我为了可读性删除了一些头
// FILE:sqliteDB头
类sqliteDB {
使用Records = std :: list< SiteCode> ;;
记录_records;
public:
void load();
记录const& get()const {return _records; }
void printList()const;
void writeJson(std :: ostream& os)const;
};
// FILE:一些sqlpp.hpp实用程序头(仅限内联实现)
#include< memory>
#include< sqlite3.h>
命名空间sqlpp {
使用database = std :: shared_ptr< :: sqlite3> ;;
void perror(int rc){
if(rc!= SQLITE_OK)throw std :: runtime_error(:: sqlite3_errstr(rc));
}
struct语句{
静态语句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; // keep it around for the lifetime of _stmt
handle _stmt;
语句(handle& h,database& db):_db(db),_stmt(std :: move(h)){}
};
数据库打开(char const * path){
:: sqlite3 * db = nullptr;
perror(:: sqlite3_open(path,& db));
返回数据库(db,:: sqlite3_close);
}
语句prepare(database db,std :: string const& sql){
return statement :: prepare(db,sql);
}
}
// FILE:sqliteDB实现文件
#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程序
template< typename List>
static void printList(List const& list){
int s = list.size();
std :: cout<< 记录数是:< s<< \\\
;
for(auto& r:list)std :: cout<< r<< ;
}
void dump(sqliteDB const& db){
printList(db.get());
std :: cout<< \\\
============== [AS JSON] =============== \\\
;
db.writeJson(std :: cout);
}
int main(){
sqliteDB db;
std :: cout<< before loading:\\\
;
dump(db);
std :: cout<< 加载后:\\\
;
db.load();
dump(db);
}
只需编译为 g ++ -std = c ++ 11 -g -Wall -Wextra -pedantic main.cpp -lsqlite3
并获取:
desktop:/ tmp $ sqlite3 database.db<< create table SiteCode(id int primary key,code int);
sehe @ desktop:/ tmp $ for a in {1..10}; do echoinsert into SiteCode(ID,CODE)VALUES($ a,$ RANDOM);;完成| sqlite3 database.db
sehe @ desktop:/ tmp $ ./test
输出
在装载之前:
记录数为:0
====== ======== [AS JSON] ===============
{}
装载后:
记录数为: 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 8798,8:20601,9:21213,10:18222}
okay, so I am banging my head on this for last couple of days but still I am unable to get it right. I have a std::list container and I want to serialize it into JSON string so that I can send it over network.
NOTE: I compile my code using following:
g++ -std=c++11 -o main main.cpp DBAccess11.cpp -lsqlite3 -lboost_serialization
Below is my DBAccess1.h file.
#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**
Below is the DBAccess11.cpp file where all the functions are defined
#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 << " ";
}
Below is 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;
}
The error I get is as follows:
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)
^
My Questions:
(1)Is this the right way to convert std::list into JSON using boost ? if NO then how should it be done ? (Note- I can only use boost and no other library )
(2) If my approach is right then what changes shall I make to correct it ?
Paths in your tree are always strings. The compiler will tell you this in the remainder of the message. Arguably the documentation is a more readable source:
Both
key_type
anddata_type
are configurable, but will usually bestd::string
here
The
self_type & put(const path_type & path, const Type & value, Translator tr);
So the essence of the fix is
pt.put(std::to_string(entry.id), entry.code);
I got a little bit side-tracked cleaning up the code, so here goes:
Self Contained Sample
// 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);
}
Just compile as g++ -std=c++11 -g -Wall -Wextra -pedantic main.cpp -lsqlite3
and get:
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
Output
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"}
这篇关于使用boost ptree将std :: list序列化为json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!