nlohmann:现代C++支持度最高的json库

2024-07-18 13:31:12 浏览数 (2)

之前推荐过json组装和解析的开源库jsoncpp,今天推荐另一款json类库nlohmann,其以对于现代C 的支持度高而著称。

下载和安装

下载链接见(https://github.com/nlohmann/json),

针对github使用有一个小技巧,如果针对这类开源库仅仅是使用其源码,并不需要一直追踪源文件,可以选择代码页面右侧中部的Release部分,下载release版本的代码集成到自己的项目中即可。

就像nlohmann库的release部分不仅支持源码的下载,也支持项目集成所需的include文件夹。如下图

集成到项目中可以直接下载include文件夹,并复制到项目所在的文件夹,通过MSVC指定附加包含目录或者使用cmake指定inlclude_directories后,便可在项目中使用nlohmann。

代码示例

待生成和解析的json字符串如下

代码语言:javascript复制
{
  "address" :
  {
    "city" : "Beijing",
    "country" : "China"
  },
  "age" : 30,
  "is_student" : false,
  "name" : "夏利",
  "subjects" :
  [
    {
        "name" : "Chinese",
        "score" : 89
    },
    {
        "name" : "English",
        "score" : 72
    },
    {
        "name" : "Math",
        "score" : 68
    }
  ]
}

生成json字符串

代码语言:javascript复制
#include"nlohmann/json.hpp"
usingnamespacenlohmann;


constexprint subject_num = 3;
std::string subject_name[subject_num] = { "Chinese","English","Math" };
intsubject_score[subject_num] = { 89,72,68 };


void using_write()
{
    json j;
    j["age"] = 30;
    j["is_student"] = false;
    j["name"]="danny";
    //封装对象方式1
    //j["address"]["city"]="beijing";
    //j["address"]["country"] = "China";


    //封装对象方式2
    j["address"]={{"city","beijing"},{"country","China"}};


   for (size_t i = 0; i < subject_num; i  )
   {
       //封装数组方式1
       //json array_item;
       //array_item["name"] = subject_name[i];
       //array_item["score"] = subject_score[i];
       //j["subjects"].emplace_back(array_item);


       //封装数组方式二
      // j["subjects"][i]["name"] = subject_name[i];
       //j["subjects"][i]["score"] = subject_score[i];
   }

   //封装数组方式三,标准容器
   std::map<std::string, int>name_score = { {"Chinese",89},{"English",72},{"Math",68} };
   json sub(name_score);
   j["subjects"]=sub;

  auto json_result =  j.dump();
  std::cout<<json_result;
}

由以上可知:

  • 该库封装对象更加方便,形式上趋近于二维数组;
  • 该库对于数组类型的封装更加方便,既可以像传统的方式,将数组中的元素视为item(参见方式一),也可以将元素直接以不同的下标形式追加到数组内,趋向于C 中容器的概念,通过[i]为其赋值(参见方式二),也可将数组内元素使用标准容器vector、list、array、dequeue、set或map、multimap等,直接构造json对象(参见方式三)

解析json字符串

代码语言:javascript复制
void using_read()
{
    const  std::string json_data = std::string(
        "{  "address" :   
    {
        "city" : "Beijing", 
        "country" : "China"     
    }, 
        "age" : 30,
        "is_student" : false,
        "name" : "danney",
        "subjects" :
        [
            {
                "name" : "Chinese",
                    "score" : 89  
            },
            {
                    "name" : "English",
                    "score" : 72  
            },
            {
                    "name" : "Math",
                    "score" : 68
            }
        ]
    }");


    auto j = json::parse(json_data);


    //隐式类型转换
   std::string name = j.at("name");


   //显示类型转换
   int age = j.at("age").get<int>();
   bool is_student;
   j.at("is_student").get_to(is_student);
   
   //解析对象
    auto city = j.at("address").at("city");
    auto country=j.at("address").at("country");


    //解析数组
    auto subjects = j.at("subjects");
    for (constauto& sub:subjects)
    {
        std::string name = sub.at("name");
        float score = sub.at("score");
        std::cout<<name<<"t"<<score<<"n";
    }
}

由以上可知

  • 该库对于对象的解析更加便捷,使用at().at()即可。
  • 该库在解析值时,可以使用隐式类型转换和显示类型转换,并且该库推荐使用显示类型转换,显示类型转换支持两种方式,一种使用模板函数get<>,一种使用get_to函数。

总结

nlohmann对于现代C 的支持度非常高,解析和生成json都很方便。但是其并不是紧凑型格式,存在占用空间大的问题,为此,其提供了多种将json对象转换成字节流的方法,在此不再赘述。

参考:

https://github.com/nlohmann/json?tab=readme-ov-file#serialization--deserialization

0 人点赞