• 极力推荐一个简单好用的C++JSON库


      极力推荐一个简单好用的C++JSON库CJsonObject,让使用json如使用C++原生的结构体那般方便,随心所欲。CJsonObject是个优秀的C++JSON库,也许会是你见过的最为简单易用的C++json库。CJsonObject的开源地址是https://github.com/Bwar/CJsonObjecthttps://gitee.com/Bwar/CJsonObject。在开源之初发布的一篇介绍CJsonObject使用的博客《轻量简单好用的C++JSON库CJsonObject》

      CJsonObject开源一年,没有刻意推广,在GitHub上获得130多star和60多fork,事实上当初把CJsonObject开源并建立一个与cJSON的fork关系(事实上CJsonObject与github上的cJSON没有任何关系,CJsonObject使用的cJSON是基于SourceForge上版本比较老的cJSON基础上修改的)是为了多引入一些流量到Bwar倾力打造的另一开源项目Nebula。没想到,倾力打造并且写了好几篇有技术含量的博客文章来推广的Nebula无论star数量还是fork数量都比CJsonObject少(可能跟受众数量有关系)。Bwar始终认为绝大部分使用JSON的场景下,易用性与开发效率才是第一位的,而不是解析性能。在易用性上,说CJsonObject让JSON如C++原生数据结构一般并不为过,所以不避黄婆卖瓜之嫌再极力推荐!CJsonObject有良好的更新和维护,对使用者提的issue响应非常及时,开源一年增加了不少原本不支持但使用者又需要的功能特性。

      CJsonObject在Bwar的重点开源项目Nebula中大量使用,无论对Bwar自己还是对外部开发者,都有持续更新维护的需要。顺便为打个小广告,Nebula是一个强大的IoC网络框架,用于以C++快速构建高并发、分布式和弹性的消息驱动应用程序。适用于即时通讯、数据采集、实时计算、消息推送、web后台服务等应用场景,Nebula已有即时通讯、埋点数据采集及实时分析的生产应用案例。如果觉得CJsonObject不错,给Nebula也点个star,谢谢。

      CJsonObject是基于cJSON全新开发一个C++版的JSON库,CJsonObject的最大优势是轻量,简单好用,开发效率极高。CJsonObject只有4个文件,拷贝到自己代码里源码级集成即可,无须编译成库,且跨平台和编译器。与大部分json解析库访问多层嵌套json非常麻烦不同,CJsonObject对多层嵌套json的读取和生成使用非常简单。

      针对开发者在博客和CJsonObject项目的issue提的问题整理了一个FAQ如下:

    FAQ

    • 1. 如何遍历json的key,并取其value?
    std::string strTraversingKey;
    std::string strTraversingValue;
    while(oJson.GetKey(strTraversingKey))
    {
        if (oJson.Get(strTraversingKey, strTraversingValue))
        {
            std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
        }
    }
    

      GetKey()遍历不适用于数组,对json数组调用GetKey()将直接返回false。调用GetKey()函数循环遍历获取当前所在层次的json key,GetKey()返回false表示已取完最后一个key,下次遍历再调用GetKey()将重新从第一个key开始获取。换一种说法,GetKey()遍历json key的返回结果为:true,true,true ... true,false; true,true,true ... true,false; true,true,true ... true,false; 想要遍历多少轮完全由用户自己决定。

      如果需要中断一次遍历并重新开始,可以调用ResetTraversing()函数重置遍历。

    std::string strTraversingKey;
    std::string strTraversingValue;
    while(oJson.GetKey(strTraversingKey))
    {
        if (strTraversingKey == "Auguest")
        {
            oJson.ResetTraversing();
            break;
        }
        if (oJson.Get(strTraversingKey, strTraversingValue))
        {
            std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
        }
    }
    
    // 因为上一个遍历中断时调用了ResetTraversing(),所以本次遍历又是从第一个key开始。如果上一个遍历中断时未调用ResetTraversing(),那这次遍历将是从上次终端的位置继续,这通常不是遍历的预期结果,因此,中断遍历时记得ResetTraversing()。
    while(oJson.GetKey(strTraversingKey))
    {
        if (oJson.Get(strTraversingKey, strTraversingValue))
        {
            std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
        }
    }
    

      __注意:__对Json当前层次的key进行Add()或Delete()操作,将导致当前遍历失效,下次调用GetKey()将获取key从头开始。

    • 2. Replace一个key时,是否需要原value类型与替换后value类型一致?

      Replace()函数对key进行替换,跟value类型无关。把一个value为int的替换为value为string,或将value替换为object或array都是可以的。但如非必要,建议替换后的value类型跟替换前的value类型相同。

    • 3. []和()的重载有什么区别,为什么要重载这两个操作符?

      []的重载是操作JsonObject或JsonArray的,为了方便一层一层往下取嵌套的json,不适用于string、int等基本json类型;()的重载是Get()系列函数的更便捷的调用,如果十分肯定key是存在的不需要通过Get()的返回值判断是否获取成功,调用()比调用Get()编码要快,不适用于操作JsonObject或JsonArray。

      []和()返回值是不一样的,两者不能混用。

    • 4. 如何用CJsonObject创建类似以下二维数组?
    {
        "test":[
            [{"test":1}],
            [{"test":2}]
        ]
    }
    

      CJsonObject对多层嵌套json的操作非常灵活方便,对嵌套json的生成和读取有许多种灵活用法。

    neb::CJsonObject oTest;
    oTest.AddEmptySubArray("test");
    for (int i = 1; i < 3; ++i)
    {
        neb::CJsonObject oDimension1;
        neb::CJsonObject oDimension2;
        oDimension2.Add("test", i);
        oDimension1.Add(oDimension2);
        oTest["test"].Add(oDimension1);
    }
    std::cout << oTest.ToString() << std::endl;
    

      这里给出的只是其中一种写法,其他几种可以参考FAQ#5。

    • 5. 请问一下在使用CJsonObject如何创建如下形式的数组?
    {
        "employees": [
            { "firstName":"John" , "lastName":"Doe" },
            { "firstName":"Anna" , "lastName":"Smith" },
            { "firstName":"Peter" , "lastName":"Jones" }
        ]
    }
    

      这里给出三种生成上述json数组的方式:

    neb::CJsonObject oJson;
    oJson.AddEmptySubArray("employees");
    oJson["employees"].Add(neb::CJsonObject("{"firstName":"John" , "lastName":"Doe"}"));
    oJson["employees"].Add(neb::CJsonObject("{"firstName":"Anna" , "lastName":"Smith"}"));
    oJson["employees"].Add(neb::CJsonObject("{"firstName":"Peter" , "lastName":"Jones"}"));
    
    neb::CJsonObject oJson;
    oJson.AddEmptySubArray("employees");
    oJson["employees"].Add(neb::CJsonObject("{}"));
    oJson["employees"][0].Add("firstName", "John");
    oJson["employees"][0].Add("lastName", "Doe");
    oJson["employees"].Add(neb::CJsonObject("{}"));
    oJson["employees"][1].Add("firstName", "Anna");
    oJson["employees"][1].Add("lastName", "Smith");
    oJson["employees"].Add(neb::CJsonObject("{}"));
    oJson["employees"][2].Add("firstName", "Peter");
    oJson["employees"][2].Add("lastName", "Jones");
    
    neb::CJsonObject oJson;
    neb::CJsonObject oJohn;
    neb::CJsonObject oAnna;
    neb::CJsonObject oPeter;
    oJohn.Add("firstName", "John");
    oJohn.Add("lastName", "Doe");
    oAnna.Add("firstName", "Anna");
    oAnna.Add("lastName", "Smith");
    oPeter.Add("firstName", "Peter");
    oPeter.Add("lastName", "Jones");
    oJson.AddEmptySubArray("employees");
    oJson["employees"].Add(oJohn);
    oJson["employees"].Add(oAnna);
    oJson["employees"].Add(oPeter);
    
  • 相关阅读:
    【iCore3 双核心板】例程九:ADC实验——电源监控
    【iCore3 双核心板】例程八:定时器PWM实验——呼吸灯
    【iCore3双核心板】扩展引脚分布
    【iCore3 双核心板】例程七:WWDG看门狗实验——复位ARM
    【iCore3 双核心板】例程六:IWDG看门狗实验——复位ARM
    【iCore3 双核心板】例程五:SYSTICK定时器实验——定时点亮LED
    【iCore3 双核心板】例程四:USART通信实验——通过命令控制LED
    【iCore3 双核心板】例程三:EXTI中断输入实验——读取ARM按键状态
    【iCore3 双核心板】例程二:读取arm按键状态
    【iCore3 双核心板】例程一:ARM驱动三色LED
  • 原文地址:https://www.cnblogs.com/bwar/p/11294452.html
Copyright © 2020-2023  润新知