首页 > 解决方案 > 如何使用 C++ 中的运行时键访问 json 文件中的值

问题描述

我是 json 新手并尝试使用 nlohmann 库,但我很困惑。

config.json 文件看起来像这样

{
    "Version": 1.1,
    "Size": 1024,
    "integer": 600,
    "Map": [{"0": "india"}, {"1": "usa"}, {"2": "china"}, {"2": "japan"}],
    "name": "xxx",
} 

我想获取 ["Map"]["1"] 的值,其中 "1" 是运行时实体。我尝试了几种方法,但没有一种方法有效。

std::string strRwFilePath = std::string(CONFIG_PATH) + "config.json";
std::ifstream RwFile(strRwFilePath);


if (RwFile.fail())
{
    std::cout << "[ReadFileContents]RwFile doesnt exist" << std::endl;
}
else 
{
    // parsing input 
    RwFile >> conf_json;

    if(!(conf_json.empty())) 
    {           
        //METHOD 1
        for (auto it = conf_json["Map"].begin(); it != conf_json["Map"].end(); ++it)
        {
            std::cout << it.key() << " | " << it.value() << "\n";
            std::string keyy = std::to_string(m_iRegionType); 
            std::string tempKey = it.key();                         //ERROR- [json.exception.invalid_iterator.207] cannot use key() for non-object iterators
            std::cout << "for loop: tempKey:" << tempKey << " \n";
            if(!strcmp(tempKey.c_str(),(std::to_string(m_iRegionType)).c_str()))
            {
                std::cout << "SUCCESS 222" << std::endl;
                break; 
            }
            else
            {
                std::cout << "FAILURE 222" << std::endl; 
            }
        }

        //METHOD 2
        for(auto& element : conf_json["Map"].items())
        {
            std::cout << element.key() << " | " << element.value() << "\n";
            m_iRegionType = 2;
            std::string keyy = std::to_string(m_iRegionType); 
            std::string tempKey = element.key();                //ERROR: [json.exception.type_error.302] type must be string, but is object
            if(!strcmp(tempKey.c_str(),(std::to_string(m_iRegionType)).c_str()))
            {
                std::cout << "SUCCESS 333" << std::endl;
                break; 
            }
            else
            {
                std::cout << "FAILURE 333" << std::endl; 
            }   
        }
        
        //METHOD 3
        std::string strTempKey = std::to_string(m_iRegionType);
        if(!conf_json["Map"][strTempKey.c_str()].is_null())
        {
            std::string strName = conf_json["Map"][strTempKey.c_str()];     //ERROR: [json.exception.type_error.305] cannot use operator[] with a string argument with array
            std::cout << "key found. RegionName: " << strName << '\n';         
        }
        else
        {
            std::cout << "key not found" << std::endl;
        }
        
        //METHOD 4
         // create a JSON object
         std::string strKey = "/Map/" + std::to_string(m_iRegionType);
         // call find
         auto it_two = conf_json.find(strKey.c_str());
        if(true == (it_two != conf_json.end()))
        {
            std::cout << "Region key was found. RegionBucketName: " << *it_two << '\n';
 
            std::string strRegionName = conf_json["Map"][m_iRegionType];
            std::string strRegionName2 = *it_two;
            std::cout << "strRegionName: " << strRegionName << '\n';
            std::cout << "strRegionName2: " << strRegionName2 << '\n';
        }
        else
        {
            //getting this as OUTPUT even though key is available
            std::cout << "invalid region type, key not available m_iRegionType: " << m_iRegionType << std::endl;

        }
        
    }
    else
    {
        std::cout << "[ReadFileContents]Read Write Json object is empty" << std::endl;
    }               
}

我也尝试过使用小型 json 结构,但无法使用运行时键访问值。

json j =
     {
     {"integer", 1},
     {"floating", 42.23},
     {"string", "hello world"},
     {"boolean", true},
     {"object", {{"key1", 1}, {"key2", 2}}},
     {"array", {1, 2, 3}}
     };

int avail4 = j.value("/integer"_json_pointer, 444);
std::cout << "avail4 : " << avail4 << std::endl;         //OUTPUT- avial4 : 1

int avail5 = j.value("/object/key2"_json_pointer, 555);
std::cout << "avail5 : " << avail5 << std::endl;         //OUTPUT- avial5 : 2

auto strKey3 = "/object/key2";
int avail6 = j.value(strKey3, 666);
std::cout << "avail6 : " << avail6 << std::endl;         //OUTPUT- avial6 : 666

任何人都可以帮助我。

标签: c++nlohmann-json

解决方案


您不能["Map"]["1"] 用来查找内部数组对象。您需要遍历数组的迭代器

代码示例可能如下所示:

#include <nlohmann/json.hpp>
#include <iostream>
// for convenience
using json = nlohmann::json;

int main() {

json j  = R"(
{
    "Version": 1.1,
    "Size": 1024,
    "integer": 600,
    "Map": [{
        "0": "india"
    }, {
        "1": "usa"
    }, {
        "2": "china"
    }, {
        "2": "japan"
    }],
    "name": "xxx"
}
)"_json;
    for (const auto& ele : j["Map"]) {
        if (ele.contains("1")) {
            std::cout << ele["1"] << std::endl;
        }
    }
}

输出:

美国

演示


推荐阅读