【问题标题】:Unhandled exception when trying to retrieve the value from the JSON ptree using Boost C++尝试使用 Boost C++ 从 JSON ptree 检索值时出现未处理的异常
【发布时间】:2022-01-01 02:35:01
【问题描述】:

使用 Boost C++ 从 JSON ptree 读取值时出现以下错误

Unhandled exception at 0x7682B502 in JSONSampleApp.exe: Microsoft C++ exception : 
boost::wrapexcept<boost::property_tree::ptree_bad_path> at memory location 0x00DFEB38.

下面是程序,有人可以帮我看看我在这里缺少什么。

#include <string>
#include <iostream>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>

using namespace std;

using boost::property_tree::ptree;

int main()
{
    const char* f_strSetting = "{\"Student\": {\"Name\":\"John\",\"Course\":\"C++\"}}";

    boost::property_tree::ptree pt1;
    std::istringstream l_issJson(f_strSetting);
    boost::property_tree::read_json(l_issJson, pt1);

    BOOST_FOREACH(boost::property_tree::ptree::value_type & v, pt1.get_child("Student"))
    {
        std::string l_strColor;
        std::string l_strPattern;
        l_strColor = v.second.get <std::string>("Name");
        l_strPattern = v.second.get <std::string>("Course");
    }
    return 0;
}

【问题讨论】:

    标签: c++ json boost boost-propertytree


    【解决方案1】:

    您的代码和数据之间的形状不匹配:

    • 数据是一个普通的嵌套字典:Student.name 是“John”。
    • 代码希望在Student 键下看到一个数组,因此它会尝试为Student 的每个子项获取Student.0.nameStudent.1.name、...。

    要么修复代码:

    // Drop the BOOST_FOREACH
    auto & l_Student = pt1.get_child("Student");
    l_strColor = l_Student.get<std::string>("Name");
    

    或修复数据:

    // Note the extra []
    const char * f_strSetting = R"({"Student": [{"Name":"John","Course":"C++"}]})";
    

    【讨论】:

    • 谢谢。 @Botje
    【解决方案2】:

    首先,我建议您对代码进行现代化改造,从而简化您的代码,同时避免使用using 指令:

    #include <boost/property_tree/json_parser.hpp>
    #include <string>
    using boost::property_tree::ptree;
    
    int main() {
        ptree pt;
        {
            std::istringstream l_issJson( R"({"Student": {"Name":"John","Course":"C++"}})");
            read_json(l_issJson, pt);
        }
    
        for(auto& [k,v] : pt.get_child("Student")) {
            auto name   = v.get<std::string>("Name");
            auto course = v.get<std::string>("Course");
        }
    }
    

    其次,您选择了错误的级别 - 正如其他答案所指出的那样。:

    #include <boost/property_tree/json_parser.hpp>
    #include <iostream>
    #include <string>
    using boost::property_tree::ptree;
    
    int main() {
        ptree pt;
        {
            std::istringstream l_issJson( R"({"Student": {"Name":"John","Course":"C++"}})");
            read_json(l_issJson, pt);
        }
    
        auto name   = pt.get<std::string>("Student.Name");
        auto course = pt.get<std::string>("Student.Course");
    
        std::cout << "Name: '" << name << "', Course: '" << course << "'\n";
    }
    

    Live

    真正的问题是:

    使用 JSON 库

    Boost 属性树不是 JSON 库。

    存在 Boost JSON:

    Live On Coliru

    #include <boost/json.hpp>
    #include <boost/json/src.hpp> // for header-only
    #include <iostream>
    #include <string>
    namespace json = boost::json;
    
    int main() {
        auto pt = json::parse(R"({"Student": {"Name":"John","Course":"C++"}})");
    
        auto& student = pt.at("Student");
        auto  name    = student.at("Name").as_string();
        auto  course  = student.at("Course").as_string();
    
        std::cout << "Name: " << name << ", Course: " << course << "\n";
    }
    

    打印

    Name: "John", Course: "C++"
    

    奖金

    对于更严肃的代码,您可能需要使用类型映射:

    #include <boost/json.hpp>
    #include <boost/json/src.hpp> // for header-only
    #include <iostream>
    #include <string>
    namespace json = boost::json;
    
    struct Student {
        std::string name, course;
    
        friend Student tag_invoke(json::value_to_tag<Student>, json::value const& v) {
            return {
                json::value_to<std::string>(v.at("Name")),
                json::value_to<std::string>(v.at("Course")),
            };
        }
    };
    
    int main()
    {
        auto doc = json::parse(R"({"Student": {"Name":"John","Course":"C++"}})");
        auto s   = value_to<Student>(doc.at("Student"));
    
        std::cout << "Name: " << s.name << ", Course: " << s.course << "\n";
    }
        
    

    Live On Coliru

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-26
      • 2021-05-26
      • 2013-05-15
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多