背景

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的源码地址如下:cJSON和json-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. html标签必备

    常用快捷键 Ctrl+c 复制 Ctrl+v 粘贴 Ctrl+x 剪切 Ctrl+a 全选 Ctrl+s 保存 Ctrl+z 撤销一步 Windows+d 返回桌面 Windows+e 我的电脑 Wi ...

  2. sqoop简单配置与使用

    sqoop(sql-to-hadoop) Apache Sqoop是用来实现结构型数据(如关系数据库)和Hadoop之间进行数据迁移的工具.它充分利用了MapReduce的并行特点以批处理的方式加快数 ...

  3. Oracle 中 流程控制函数 decode用法

    函数介绍 DECODE函数是ORACLE PL/SQL的功能强大的函数之一,目前还只有ORACLE公司的SQL提供了此函数,其它数据库厂商的SQL实现还没有此功能. DECODE有什么用途呢?先构造一 ...

  4. Python 基于urllib.request封装http协议类

    基于urllib.request封装http协议类 by:授客QQ:1033553122 测试环境: Python版本:Python 3.3   代码实践 #!/usr/bin/env python ...

  5. [20171124]bbed的使用问题2.txt

    [20171124]bbed的使用问题2.txt --//bbed 是探究oracle数据块的好工具,有时候不用转储,直接可以它看oracle内部块的内部结构.--//在使用中要注意一些问题,昨天又犯 ...

  6. Asp.net 中ViewState,cookie,session,application,cache的比较

    Asp.net 中的状态管理维护包含ViewState,cookie,session,application,cache五种方式,以下是它们的一些比较: 1.存在于客户端还是服务端 客户端: view ...

  7. 安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details"错误.原因是启动"VisualSVN Server"失败

    安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server ...

  8. NetBeans数据库笔记---三层架构

    1.创建数据库,数据表 用MySQL数据库和Navicat for MySQL工具创建表 2.创建实体类——反应表结构(列——变量) 也就是对应表建立的gets和sets方法,实体类的名字一般都与数据 ...

  9. 阿里云上安装pip3(Ubuntu)

    安装pip3: 这个简单啊,到网上下载get-pip.py的脚本,然后scp到你的阿里云服务器上,python3 get-pip.py即可. 如果不会scp,哈哈,按照下面的几步: wget http ...

  10. mysql启动失败一例

    操作系统版本:Ubuntu 13.04 mysql 版本:mysql-server-5.5 现象:突然之前接到报告说数据库启不来了.第一时间查看硬盘空间,看是否硬盘满了.发现空间使用正常. root@ ...