簡體   English   中英

如何從我的數據創建 JSON 文件? (使用С++,提升json)

[英]How create a JSON-file from my data? (with С++, boost json)

我想創建一個 Json 文件,它將根據之前收到的數據創建。 我根本不明白如何使用 Json 文件。 我想使用 Boost 庫,因為我在該程序的另一部分中使用它。 我需要創建一個具有特定結構的 Json 文件,我附在下面。

我需要得到 JSON:

{
  "track": {
    "Wheels": {
      "Wheel": [
        {
          "start_pos": "10",
          "end_pos": "25"
        },
        {
          "start_pos": "22",
          "end_pos": "78"
        }
      ]
    },
    "Brakes": {
      "Brake": [
        {
        "start_pos": "10",
        "midl_pos": "25"
        }
      ]
    }
  }
}

C++:

#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include <string>
using namespace std;
using boost::property_tree::ptree;

struct wheel
{
    string start_pos;
    string end_pos;
};

struct brake
{
    string start_pos;
    string midl_pos;
};

int main() 
{
    string tr = "track";
    string ws = "Wheels";
    string bs = "Brakes";

    struct wheel w1;
    w1.start_pos = "10";
    w1.end_pos = "25";

    struct wheel w2;
    w2.start_pos = "22";
    w2.end_pos = "78";

    struct brake b1;
    b1.start_pos = "10";
    b1.midl_pos = "25";

    return 0;
}

使用Boost JSON 定制點來實現它。

做測試驅動:

住在科利魯

#include "boost/json/src.hpp" // header-only approach
#include <iostream>
namespace json = boost::json;
using json::value_from;
using json::value_to;

static const json::value expected = json::parse(R"({
  "track": {
    "Wheels": {
      "Wheel": [
        {
          "start_pos": "10",
          "end_pos": "25"
        },
        {
          "start_pos": "22",
          "end_pos": "78"
        }
      ]
    },
    "Brakes": {
      "Brake": [
        {
        "start_pos": "10",
        "midl_pos": "25"
        }
      ]
    }
  }
})");

namespace MyLib {
    struct wheel { int start_pos, end_pos; };
    struct brake { int start_pos, midl_pos; };

    struct track {
        std::vector<wheel> wheels;
        std::vector<brake> brakes;
    };

    void tag_invoke(json::value_from_tag, json::value& jv, wheel const& w) {
        jv = {
            {"start_pos", std::to_string(w.start_pos)},
            {"end_pos", std::to_string(w.end_pos)},
        };
    }

    void tag_invoke(json::value_from_tag, json::value& jv, brake const& b) {
        jv = {
            {"start_pos", std::to_string(b.start_pos)},
            {"midl_pos", std::to_string(b.midl_pos)},
        };
    }

    void tag_invoke(json::value_from_tag, json::value& jv, track const& t) {
        jv = {{"track",
               {
                   {"Wheels", {{"Wheel", t.wheels}}},
                   {"Brakes", {{"Brake", t.brakes}}},
               }}};
    }
}

int main() 
{
    MyLib::track track{{
                           {10, 25},
                           {22, 78},
                       },
                       {
                           {10, 25},
                       }};

    json::value output = json::value_from(track);
    std::cout << output << "\n";

    std::cout << expected << "\n";
    std::cout << "matching: " << std::boolalpha << (output == expected) << "\n";
}

印刷

{"track":{"Wheels":{"Wheel":[{"start_pos":"10","end_pos":"25"},{"start_pos":"22","end_pos":"78"}]},"Brakes":{"Brake":[{"start_pos":"10","midl_pos":"25"}]}}}
{"track":{"Wheels":{"Wheel":[{"start_pos":"10","end_pos":"25"},{"start_pos":"22","end_pos":"78"}]},"Brakes":{"Brake":[{"start_pos":"10","midl_pos":"25"}]}}}
matching: true

獎金

添加完整的往返支持。 我選擇刪除to_string ,因為它看起來可能只是 Boost 屬性樹限制的要求:

住在科利魯

#include "boost/json/src.hpp" // header-only approach
#include <iostream>
namespace json = boost::json;
using json::value_from;
using json::value_to;

namespace MyLib {
    struct wheel {
        int start_pos, end_pos;
        bool operator==(wheel const&) const = default;
    };
    struct brake {
        int start_pos, midl_pos;
        bool operator==(brake const&) const = default;
    };

    struct track {
        std::vector<wheel> wheels;
        std::vector<brake> brakes;
        bool operator==(track const&) const = default;
    };

    void tag_invoke(json::value_from_tag, json::value& jv, wheel const& w) {
        jv = {{"start_pos", w.start_pos}, {"end_pos", w.end_pos}};
    }
    void tag_invoke(json::value_from_tag, json::value& jv, brake const& b) {
        jv = {{"start_pos", b.start_pos}, {"midl_pos", b.midl_pos}};
    }
    void tag_invoke(json::value_from_tag, json::value& jv, track const& t) {
        jv = {{"track",
               {
                   {"Wheels", {{"Wheel", t.wheels}}},
                   {"Brakes", {{"Brake", t.brakes}}},
               }}};
    }

    wheel tag_invoke(json::value_to_tag<wheel>, json::value const& jv) {
        return {
            value_to<int>(jv.at("start_pos")),
            value_to<int>(jv.at("end_pos")),
        };
    }
    brake tag_invoke(json::value_to_tag<brake>, json::value const& jv) {
        return {
            value_to<int>(jv.at("start_pos")),
            value_to<int>(jv.at("midl_pos")),
        };
    }
    track tag_invoke(json::value_to_tag<track>, json::value const& jv) {
        auto& track = jv.at("track");
        return {
            value_to<decltype(track::wheels)>(track.at("Wheels").at("Wheel")),
            value_to<decltype(track::brakes)>(track.at("Brakes").at("Brake")),
        };
    }
}

int main() 
{
    MyLib::track const track{{
                           {110, 125},
                           {111, 126},
                           {142, 198},
                       },
                       {
                           {10, 25},
                           {120, 135},
                       }};

    json::value output = json::value_from(track);
    std::cout << output << "\n";

    std::cout << "Roundtrip: " << std::boolalpha
              << (value_to<MyLib::track>(output) == track) << "\n";
}

印刷

{"track":{"Wheels":{"Wheel":[{"start_pos":110,"end_pos":125},{"start_pos":111,"end_pos":126},{"start_pos":142,"end_pos":198}]},"Brakes":{"Brake":[{"start_pos":10,"midl_pos":25},{"start_pos":120,"midl_pos":135}]}}}
Roundtrip: true

盡管有評論建議他們可以使用不同的庫,但我認為@Nindzzya 想專門使用 boost 庫。

使用How to use boost::property_tree 中的 boost 庫來加載和編寫 JSON

#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include <string>
#include <iostream>
using namespace std;
namespace pt = boost::property_tree;

struct wheel
{
    string start_pos;
    string end_pos;
};

struct brake
{
    string start_pos;
    string midl_pos;
};

int main() 
{
    string tr = "track";
    string ws = "Wheels";
    string bs = "Brakes";

    struct wheel w1;
    w1.start_pos = "10";
    w1.end_pos = "25";

    struct wheel w2;
    w2.start_pos = "22";
    w2.end_pos = "78";

    struct brake b1;
    b1.start_pos = "10";
    b1.midl_pos = "25";

    pt::ptree wheel1, wheel2, wheels, wheel;
    pt::ptree brake1, brakes, brake;
    pt::ptree track, root;

    wheel1.put("start_pos", w1.start_pos);
    wheel1.put("end_pos", w1.end_pos);

    wheel2.put("start_pos", w2.start_pos);
    wheel2.put("end_pos", w2.end_pos);

    wheels.push_back(make_pair("", wheel1));
    wheels.push_back(make_pair("", wheel2));

    wheel.add_child("Wheel", wheels);
    track.add_child(ws, wheel);


    brake1.put("start_pos", b1.start_pos);
    brake1.put("midl_pos", b1.midl_pos);

    brakes.push_back(make_pair("", brake1));

    brake.add_child("Brake", brakes);
    track.add_child(bs, brake);

    root.add_child(tr, track);

    pt::write_json(std::cout, root);

    return 0;
}

結果是:

{
    "track": {
        "Wheels": {
            "Wheel": [
                {
                    "start_pos": "10",
                    "end_pos": "25"
                },
                {
                    "start_pos": "22",
                    "end_pos": "78"
                }
            ]
        },
        "Brakes": {
            "Brake": [
                {
                    "start_pos": "10",
                    "midl_pos": "25"
                }
            ]
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM