C++ 抛出异常,指示错误JSON数据的位置,而不发送垃圾邮件try/catch块

C++ 抛出异常,指示错误JSON数据的位置,而不发送垃圾邮件try/catch块,c++,json,C++,Json,我有一个带有设置列表的复杂JSON对象,类似这样(示例有点做作): { “配置”:{ “名称”:“, “玩家”{“最小”:3,“最大”:5}, “选择”:{ “轮数”:{“提示”:“输入轮数”,“默认值”:10}, “得分到获胜”:{“提示”:“输入得分到获胜”,“默认值”:500} } } //…许多其他信息,可以嵌套得很深 } 我可以这样处理它(使用nlohmann json): void parse_json(const nlohmann::json&j){ nlohmann::json

我有一个带有设置列表的复杂JSON对象,类似这样(示例有点做作):

{
“配置”:{
“名称”:“,
“玩家”{“最小”:3,“最大”:5},
“选择”:{
“轮数”:{“提示”:“输入轮数”,“默认值”:10},
“得分到获胜”:{“提示”:“输入得分到获胜”,“默认值”:500}
}
}
//…许多其他信息,可以嵌套得很深
}
我可以这样处理它(使用nlohmann json):

void parse_json(const nlohmann::json&j){
nlohmann::json config=j.at(“配置”);
std::string name=config.at(“name”);
int minplayers=config.at(“players”).at(“min”);
int maxplayers=config.at(“players”).at(“max”);
对于(auto&it:config.at(“选项”).items()){
std::string key=it.key();
std::string prompt=it.value().at(“prompt”);
int deffal=it.value().at(“默认值”);
}
}
但如果JSON不正确,则不会给出非常有用的错误消息:

试试看{
parse_json(nlohmann::json::parse(R)({“配置”:{
“名称”:“酷房名称”,
“玩家”:{“最小”:4,“最大”:“6”},
“选择”:{
“轮数”:{“提示”:“输入轮数”,“默认值”:10},
“得分到获胜”:{“提示”:“输入得分到获胜”,“默认值”:500}
}
}})"));
}捕获(标准::异常和例外){

std::cout您可以跟踪最后访问的路径(作为JSON指针)并报告错误:

void parse_json(const nlohmann::json &j) {
    nlohmann::json::json_pointer last_accessed;
    auto at = [&j, &last_accessed](const nlohmann::json::json_pointer& ptr) {
        last_accessed = ptr;
        return j.at(ptr);
    };
    try {
        auto config_ptr = "/configuration"_json_pointer;
        nlohmann::json config = at(config_ptr);
        std::string name = at(config_ptr / "name");
        ...
    } catch (...) {
        throw last_accessed;
    }
}

使用稍微聪明一点的异常类型,您可以报告底层nlohmann::json错误,但我希望您能了解其要点。

您可以跟踪最后访问的路径(作为json指针)并报告错误:

void parse_json(const nlohmann::json &j) {
    nlohmann::json::json_pointer last_accessed;
    auto at = [&j, &last_accessed](const nlohmann::json::json_pointer& ptr) {
        last_accessed = ptr;
        return j.at(ptr);
    };
    try {
        auto config_ptr = "/configuration"_json_pointer;
        nlohmann::json config = at(config_ptr);
        std::string name = at(config_ptr / "name");
        ...
    } catch (...) {
        throw last_accessed;
    }
}

使用稍微聪明一点的异常类型,您可以报告底层nlohmann::json错误,但我希望您能了解其要点。

基于@Botje的想法,我创建了一个帮助器类来更新json指针。下面是:

#包括
#包括“nlohmann/json.hpp”
/* 
LastAccessedHelper(json,json_指针)
使用JSON对象和JSON_指针构造以存储访问路径
支持常量或非常量访问,请相应更改定义中的类型别名
下面的“arg”可以是json指针、字符串或大小
at(arg)-在给定位置返回json
at()-在根目录下访问json——有效地将助手“转换”为json对象
输入(arg)-将上次访问的对象移动到新位置,并基于新位置返回子助手
exit()-告诉子助手将上次访问的\u移回上一个位置
*/
//helper函数,用于计算指针中的级别数,无本机方法
int json_ptr_大小(常量nlohmann::json::json_指针&_ptr){
//复制并弹出_back(),直到根目录:(
nlohmann::json::json_指针ptr(_ptr);
int size=0;
而(!ptr.empty()){
ptr.pop_back();
大小++;
}
返回大小;
}
结构LastAccessedHelper{
using json=const nlohmann::json;//根据您的用例设置为const或non-const
使用json_指针=nlohmann::json::json_指针;
json&j;
json_指针&上次访问的_;
int在_级;
int-exit_级;
LastAccessedHelper(json&j、json\u指针和上次访问)
:j{j},上次访问{上次访问},在{0}级别,退出{0}
{}
LastAccessedHelper(json&j、json\u指针和上次访问、int-exit\u级别)
:j{j},上次访问{上次访问},在{0}级,退出}
{}
/*at()-在给定位置返回json*/
json和at(常量json_指针和ptr){
重置();
at_级别=json_ptr_大小(ptr);
最后访问的\u/=ptr;
返回j.at(ptr);
}
json&at(const std::string&s){
返回(json_pointer()/s);
}
json和at(大小){
返回(json_pointer()/t);
}
/*at()无参数-“转换”LastAccessedHelper为json对象*/
json&at(){
返回(json_pointer());
}
/*enter()-将上次访问的对象移动到新位置,并基于新位置返回子助手*/
LastAccessedHelper输入(常量json_指针和ptr){
重置();
最后访问的\u/=ptr;
返回LastAccessedHelper(j.at(ptr)、last_访问、json_ptr_大小(ptr));
}
LastAccessedHelper输入(常量std::string&s){
返回回车(json_pointer()/s);
}
LastAccessedHelper输入(大小\u t){
返回回车(json_pointer()/t);
}
/*exit()-告诉子助手将上次访问的\u移回上一个位置*/
无效退出(){
重置();
退绕(退出_级);
退出_级别=0;
}
/*助手*/
无效展开(整数级别){

对于(inti=0;i基于@Botje的想法,我创建了一个helper类来更新json指针

#包括
#包括“nlohmann/json.hpp”
/* 
LastAccessedHelper(json,json_指针)
使用JSON对象和JSON_指针构造以存储访问路径
支持常量或非常量访问,请相应更改定义中的类型别名
下面的“arg”可以是json指针、字符串或大小
at(arg)-在给定位置返回json
at()-在根目录下访问json——有效地将助手“转换”为json对象
输入(arg)-将上次访问的对象移动到新位置,并基于新位置返回子助手
exit()-告诉子助手将上次访问的\u移回上一个位置
*/
//helper函数,用于计算指针中的级别数,无本机方法
int json_ptr_大小(常量nlohmann::json::json_指针&_ptr){
//复制并弹出_back(),直到根目录:(
nlohmann::json::json_指针ptr(_ptr);
int size=0;
而(!ptr.empty()){
ptr.pop_back();
大小++;
}
返回大小;
}
结构LastAccessedHelper{
使用js