首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Boost序列化和反序列化JSON

使用Boost序列化和反序列化JSON
EN

Stack Overflow用户
提问于 2012-09-13 02:49:12
回答 3查看 63.8K关注 0票数 71

我是C++的新手。使用boost序列化和反序列化std::Map类型的数据的最简单方法是什么?我找到了一些使用PropertyTree的例子,但它们对我来说很晦涩难懂。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-05 04:09:56

请注意,property_tree将键解释为路径,例如,将对"a.b"="z“将创建一个{"a":{"b":"z"}} JSON,而不是{"a.b":"z"}。否则,使用property_tree就很简单了。下面是一个小示例。

代码语言:javascript
复制
#include <sstream>
#include <map>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

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

void example() {
  // Write json.
  ptree pt;
  pt.put ("foo", "bar");
  std::ostringstream buf; 
  write_json (buf, pt, false);
  std::string json = buf.str(); // {"foo":"bar"}

  // Read json.
  ptree pt2;
  std::istringstream is (json);
  read_json (is, pt2);
  std::string foo = pt2.get<std::string> ("foo");
}

std::string map2json (const std::map<std::string, std::string>& map) {
  ptree pt; 
  for (auto& entry: map) 
      pt.put (entry.first, entry.second);
  std::ostringstream buf; 
  write_json (buf, pt, false); 
  return buf.str();
}
票数 96
EN

Stack Overflow用户

发布于 2021-02-03 00:15:26

Boost版本1.75及更高版本现在有一个健壮的原生JSON库:

https://www.boost.org/doc/libs/develop/libs/json/doc/html/index.html

我不建议再使用Boost.PropertyTree的JSON算法,因为它们并不完全符合规范。

票数 3
EN

Stack Overflow用户

发布于 2020-11-08 06:47:30

一些公司要求我实现JSON序列化库,它比boost lib更快。我做到了-它比boost lib快了大约10倍。我发布代码以供任何人使用。

代码语言:javascript
复制
#pragma once
#include <string>
#include <vector>
#include <regex>
#include <fstream>

enum class JsonNodeType { Array, Object, String };

class JsonNode
{
    JsonNodeType m_nodeType;
    
    std::vector<JsonNode*>* m_values{0};
    std::vector<std::string>* m_keys{0};
    std::string m_value{};
    inline static int m_indent;
    inline static bool m_formatOutput;
    const int m_indentInc{4};

public:

    JsonNode(JsonNodeType type) 
    {
        m_nodeType = type;
        
        switch (m_nodeType) {
            case JsonNodeType::Object: m_keys = new std::vector<std::string>();
                                       [[fallthrough]];
            case JsonNodeType::Array: m_values = new std::vector<JsonNode*>();
        }
    };

    JsonNode(std::string value) 
    {
        m_nodeType = JsonNodeType::String;
        m_value = value;
    }

    ~JsonNode() 
    {

        if (m_values)       
            for (JsonNode* node : *m_values)
                delete node;
                
        delete m_values; 
        delete m_keys; 
    }

    void Add(JsonNode* node) 
    {               
        assert(m_nodeType == JsonNodeType::Array);
        
        m_values->push_back(node);
    }

    void Add(const char* key, JsonNode* node) 
    {       
        assert(m_nodeType == JsonNodeType::Object);

        m_values->push_back(node);
        m_keys->push_back(key);
    }

    void Add(const char* key, std::string value) 
    {       
        assert(m_nodeType == JsonNodeType::Object);

        m_keys->push_back(key);
        m_values->push_back(new JsonNode(value));
    }

    void Add(std::string value) 
    {
        assert(m_nodeType == JsonNodeType::Array);

        m_values->push_back(new JsonNode(value));
    }

    void Add(int value) 
    {
        assert(m_nodeType == JsonNodeType::Array);

        m_values->push_back(new JsonNode(std::to_string(value)));
    }

    void Add(const char* key, bool value) 
    {
        assert(m_nodeType == JsonNodeType::Object);

        m_keys->push_back(key);
        m_values->push_back(new JsonNode(value ? "true" : "false"));
    }


    void OutputToStream(std::ostream& ofs, bool formatOutput = true) 
    {
        m_indent = 0;       
        m_formatOutput = formatOutput;

        OutputNodeToStream(ofs);

        ofs << std::endl;
    }

    std::string EscapeString(std::string& str) 
    {   
        std::regex html2json("\\\\|\\/|\\\"");
        std::regex newline("\n");

        std::string tmp = std::regex_replace(str, html2json, "\\$&");   
        return std::regex_replace(tmp, newline, "\\n");
    }

private: 

    void OutputNodeToStream(std::ostream& ofs) 
    {
        switch (m_nodeType) {

            case JsonNodeType::String:
                ofs << "\"" << m_value << "\"";
                break;

            case JsonNodeType::Object:
                OutputObjectToStream(ofs);
                break;

            case JsonNodeType::Array:
                OutputArrayToStream(ofs);
                break;
        }

    }

    void ChangeIndent(std::ostream& ofs, int indentDelta) 
    {

        if (!m_formatOutput)
            return;

        m_indent += indentDelta;
        
        ofs << std::endl;
    }

    void OutputIndents(std::ostream& ofs) 
    {

        if (!m_formatOutput)
            return;

        for (int i = 0; i < m_indent; i++)
            ofs << " ";
    }

    void OutputObjectToStream(std::ostream& ofs) 
    {

        assert(m_nodeType == JsonNodeType::Object);
        assert(m_keys->size() == m_values->size());

        if (m_keys->empty()) 
        {
            ofs << "\"\"";
            return;
        }

        ofs << "{";     

        ChangeIndent(ofs, m_indentInc);
        
        for (int i = 0; i < m_keys->size(); i++) 
        {
            
            if (i > 0)
                ofs << ",";

            if (i > 0 && m_formatOutput)
                ofs << std::endl;

            
            OutputIndents(ofs);

            ofs << "\"" << m_keys->at(i) << "\": ";

            m_values->at(i)->OutputNodeToStream(ofs);
        }   
        
        ChangeIndent(ofs, -m_indentInc);
        OutputIndents(ofs);
        ofs << "}";     
    }

    void OutputArrayToStream(std::ostream& ofs) 
    {
    
        assert(m_nodeType == JsonNodeType::Array);

        if (m_values->empty()) 
        {
            ofs << "\"\"";
            return;
        }

        ofs << "[";

        ChangeIndent(ofs, m_indentInc);

        for (int i = 0; i < m_values->size(); i++) 
        {

            if (i > 0)
                ofs << ",";

            if(i > 0 && m_formatOutput)
                ofs << std::endl;

            OutputIndents(ofs);         

            m_values->at(i)->OutputNodeToStream(ofs);
        }
        
        ChangeIndent(ofs, -m_indentInc);
        OutputIndents(ofs);
        ofs << "]";     
    }

};

使用示例

创建json树:

代码语言:javascript
复制
JsonNode* Circuit::GetMyJson()
{
    JsonNode* node = new JsonNode(JsonNodeType::Object);

    JsonNode* gates = new JsonNode(JsonNodeType::Array);

    for (auto& [k, v] : m_gates)
        gates->Add(v.GetMyJson());

    node->Add("gates", gates);

    return node;
}

输出树:

代码语言:javascript
复制
std::unique_ptr<JsonNode> node (simulation->GetMyJson());
std::ofstream output("output.json", std::ios::out);
node->OutputToStream(output);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12394472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档