背景

JSON即JavaScript Object Notation,是一种轻量级的数据交换格式。

JSON建构于两种结构:

  • “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

关于JSON库的性能评测与标准符合程度,可以参照《28 个 C/C++ 开源 JSON 程序库性能及标准符合程度评测》,另一个英文版更详细结果在nativejson-benchmark

在阅读了一系列评测之后,结合需求(ROM尽量小,RAM尽量小,带处理的数据比较简单),准备研究一下cJSON和json-c。

JSON官网获得json-c和cJSON的源码地址如下:cJSONjson-c

下面就基于这两份代码在Ubuntu进行速度和兼容性测试。

测试标的构造对于测试的覆盖以及测试有效性非常重要,所幸的在AOSP中有一个参考AOSP/external/jsoncpp/test。

cJSON

下载代码:

git clone https://github.com/arnoldlu/cJSON.git

编译安装:

mkdir build
cd build
cmake .. -DENABLE_CJSON_UTILS=Off -DENABLE_CJSON_TEST=On -DCMAKE_INSTALL_PREFIX=/usr (生成bin+lib)
cmake .. -DENABLE_CJSON_UTILS=Off -DENABLE_CJSON_TEST=On -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=Off (生成bin)
make
sudo make install (安装libcjson.so)

使用实例

参考文档:《使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解》、《cJSON学习笔记》。

下面是一个构造JSON数据,然后解析,打印Type-Key-Value的小示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

void printJson(cJSON *root)
{
    if(!root)
    {
        printf("NULL JSON root.\n");
        return;
    }
   
    printf("Type=0x%02x, %s=%s\n", root->type, root->string, cJSON_Print(root));  cJSON_Print会根据类型打印
}

static char * makeJson(void)
{
    cJSON *pJsonRoot = NULL;
    cJSON *pSubJson = NULL;
    char *p = NULL;

pJsonRoot = cJSON_CreateObject();
    if(NULL == pJsonRoot)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        return NULL;
    }
    cJSON_AddStringToObject(pJsonRoot, "hello", "hello world");  String类型
    cJSON_AddNumberToObject(pJsonRoot, "number", 10010);  Number类型
    cJSON_AddBoolToObject(pJsonRoot, "bool", 1);  bool类型
    pSubJson = cJSON_CreateObject();  创建一个cJSON,用于嵌套数据
    if(NULL == pSubJson)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddStringToObject(pSubJson, "subjsonobj", "a sub json string");  在子cJSON下,增加一个String类型数据
    cJSON_AddItemToObject(pJsonRoot, "subobj", pSubJson);  将子cJSON加入到pJsonRoot

p = cJSON_Print(pJsonRoot);
    if(NULL == p)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        cJSON_Delete(pJsonRoot);
        return NULL;
    }

cJSON_Delete(pJsonRoot);

return p;
}

static void parseJson(char * pMsg)
{
    cJSON *pJson;
    cJSON *pSub;
    cJSON * pSubSub;

if(NULL == pMsg)
    {
    return;
    }

pJson = cJSON_Parse(pMsg);
    if(NULL == pJson)                                                                                        
    {
        return ;
    }

pSub = cJSON_GetObjectItem(pJson, "hello");
    printJson(pSub);

pSub = cJSON_GetObjectItem(pJson, "number");
    printJson(pSub);

pSub = cJSON_GetObjectItem(pJson, "bool");
    printJson(pSub);

pSub = cJSON_GetObjectItem(pJson, "subobj");
    printJson(pSub);

pSubSub = cJSON_GetObjectItem(pSub, "subjsonobj");
    printJson(pSubSub);

cJSON_Delete(pJson);
}

int main(void)
{
    char *p;

/* print the version */
    printf("Version: %s\n", cJSON_Version());  获取cJSON版本号

p = makeJson();  构造JSON数据
    if(NULL == p)
    {
        return 0;
    }
    printf("p = \n%s\n\n", p);  打印构造的字符串
    parseJson(p);  解析JSON数据,并打印Type-Key-Value
    free(p);
    return 0;
}

在安装(sudo make install)cJSON之后,编译的时候需要跟上libcjson库文件:

gcc demo.c -o demo -lcjson

执行结果如下:

Version: 1.3.2
p =
{
    "hello":    "hello world",
    "number":    10010,
    "bool":    true,
    "subobj":    {
        "subjsonobj":    "a sub json string"
    }
}

Type=0x10, hello="hello world"
Type=0x08, number=10010
Type=0x02, bool=true
Type=0x40, subobj={
    "subjsonobj":    "a sub json string"
}
Type=0x10, subjsonobj="a sub json string"

json-c

参考文档:《JSON C库的使用

下载代码:

git clone https://github.com/arnoldlu/json-c.git

编译安装:

sh autogen.sh
./configure
make
make install

JSON构造/解析(by C)---cJSON和json-c的更多相关文章

  1. 奇葩json结构解析--key是数字的json处理

    json结构如下: { "ret": "ok", "data": { "57230": { "cat_id&q ...

  2. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  3. 【spark】文件读写和JSON数据解析

    1.读文件 通过 sc.textFile(“file://") 方法来读取文件到rdd中. val lines = sc.textFile("file://")//文件地 ...

  4. 多叉树结构:JSON数据解析(一)

    多叉树结构:JSON数据解析(一) 最近做一个实时数据搜索引擎的项目中,在项目架构的偏顶层需要写一个JSON数据解析的模块,由于目前JSON解析没有现成统一开源框架可以利用,目前只是手工利用com.a ...

  5. JSON在线解析及格式化校验工具 jsonin.com

    JSON在线解析及格式化校验工具 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它使得人们很容易的进行阅读和编写.同时也方便了机器进行解析和生成.它是基 ...

  6. 校验字符串是否是JSON格式,将不规则展示的json格式的字符串进行规则展示(json格式化)

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   var str = {"code": "","svcname" ...

  7. json系列(一)cjson,rapidjson,yyjson解析示例

    前言 项目上通过消息中间件传输json格式的数据,其他接收模块需要对json格式的数据进行解析,反序列化.对json解析工具有几个关注点,一是具备解析和构造的基础功能,二是具备解析和构造的高性能,三是 ...

  8. json 构造和解析

    目录: (1)引入jar包: (2)json的构造: (3)json的解析: (4)遍历未知key. (1)java对json的处理,可借助org.json.jar. <!-- https:// ...

  9. JSON格式解析和libjson使用简介(关于cjson的使用示例)

    JSON格式解析和libjson使用简介 在阅读本文之前,请先阅读下<Rss Reader实例开发之系统设计>一文. Rss Reader实例开发中,进行网络数据交换时主要使用到了两种数据 ...

随机推荐

  1. Python 正则介绍

    正则表达式是一种小型的,高度专业化的变成语言,在 Python 中,它通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的引擎执行. findall() 方法,所有匹配的结 ...

  2. csharp:FTP Client Library using FtpWebRequest or Sockets

    https://netftp.codeplex.com/SourceControl/latest http://ftplib.codeplex.com/ https://www.codeproject ...

  3. 【读书笔记】iOS-分类与协议

    分类与协议是Object-C特有概念,分类(Category)可以认为是一种继承性的扩展,而协议(Protocol)可以理解为Java中的Interface(接口)或者C++的纯虚类. 参考资料:&l ...

  4. Spring装配bean(在java中进行显式配置)

    1.简单介绍 Spring提供了三种装配机制: 1.在XML中进行显式配置: 2.在java中进行显式配置: 3.隐式的bean发现机制和自动装配. 其中,1和3项在项目中经常使用,而在java中进行 ...

  5. vue.js及项目实战[笔记]— 05 WebPack

    一. 历史介绍 1. 规范 AMD Commonjs||CMD UMD 参考:认识AMD.CMD.UMD.CommonJS 2. 工具 npm bower webpack browserify 参考: ...

  6. spring资源访问接口和资源加载接口

    spring 资源访问接口 JDK提供的资源访问类,如java.net.URL.File等,不能很好地满足各种资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类. 鉴于此,spr ...

  7. Dell XPS 13 9306安装 macOS 10.12.6

    一直在考虑买一个手上的本,轻薄,办公方便.个人很喜欢mac 下的那些软件,尤其是keynote.就锁定在Macbook Pro上,但是又觉得没有什么玩头,后来一直找,觉得xps也很符合要求,就开始调查 ...

  8. windows端ndk 编译.c/cpp文件生成so库示例

  9. Sql Server 增加字段、修改字段、修改类型、修改默认值

    1.修改字段名: alter table 表名 rename column A to B 2.修改字段类型: alter table 表名 alter column 字段名 type not null ...

  10. Jquery+asp.net实现Ajax方式文件下载实例代码

    如果文件中,需要下载一个文件,一般用超级链接的方式即可. 但是如果是图片,浏览器会默认打开图片浏览,不是实现下载. 考虑可以使用jquery ajax提交form请求的方式. jquery downl ...