网上看到的一片关于json-c的文章。收藏一下,忘记了出处,尽请作者谅解。

JSON c语言开发指南

 

1.    引言

本文档是基于json-c 库对数据交换进行开发所编写的开发指南,及详细解释json-c库中常用api。 适用于开发人员使用c语言对json的编程。

(注:  此文档json-c库版本为0.8——json-c-0.8)

2.    JSON简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

跟XML相比,JSON的优势在于格式简洁短小,特别是在处理大量复杂数据的时候,这个优势便显得非常突出。从各浏览器的支持来看,JSON解决了因不同浏览器对XML DOM解析方式不同而引起的问题。

2.1 JSON建构于两种结构:

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

这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

2.2 JSON具有以下这些形式:

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。

数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。

值(value)可以是双引号括起来的字符串(string)、数值(number)、truefalsenull、对象(object)或者数组(array)。这些结构可以嵌套。

字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

字符串(string)与C或者Java的字符串非常相似。

数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

3.    JSON 库函数说明

3.1 JSON对象的生成

Json对象的类型:

json_type_object, “名称/值”对的集合

Json对象的值类型

json_type_boolean,

json_type_double,

json_type_int,

json_type_array, “值”的集合

json_type_string

struct json_object * json_object_new_object();

说明:

创建个空的json_type_object类型JSON对象。

struct json_object* json_object_new_boolean(Boolean b);

说明:

创建个json_type_boolean值类型json对象

Boolean json_object_get_boolean(struct json_object *obj);

说明:

从json对象中boolean值类型得到boolean值

同样:

struct json_object* json_object_new_int(int i)

int json_object_get_int(struct json_object *this)

struct json_object* json_object_new_double(double d)

double json_object_get_double(struct json_object *this)

struct json_object* json_object_new_string(char *s)

char* json_object_get_string(struct json_object *this)

struct json_object * json_object_new_array();

说明:

创建个空的json_type_array类型JSON数组值对象。

struct json_object * json_tokener_parse(char *str);

说明:

由str里的JSON字符串生成JSON对象,str是json_object_to_json_string() 生成的。

参数:

str – json字符串

struct json_object * json_object_object_get(struct json_object * json,char *name);

说明:

从json中按名字取一个对象。

参数:

json – json对象

name -  json域名字

3.2 JSON对象的释放

struct json_object * * json_object_get(struct json_object * this)

说明:

增加对象引用计数。使用c库最关心的是内存谁来分配, 谁来释放. jsonc的内存管理方式, 是基于引用计数的内存树(链), 如果把一个struct json_object 对象a, add到另一个对象b上, 就不用显式的释放(json_object_put) a了, 相当于把a挂到了b的对象树上, 释放b的时候, 就会释放a. 当a既add到b上, 又add到对象c上时会导致a被释放两次(double free), 这时可以增加a的引用计数(调用函数json_object_get(a)), 这时如果先释放b, 后释放c, 当释放b时, 并不会真正的释放a, 而是减少a的引用计数为1, 然后释放c时, 才真正释放a.

参数:

this – json对象

Void json_object_put(struct json_object * this)

说明:

减少对象引用次数一次,当减少到0就释放(free)资源

参数:

this – json对象

样例片段:

my_string = json_object_new_string("\t");

/*输出 my_string=   */ \t(table键)

printf("my_string=%s\n", json_object_get_string(my_string));

/*转换json格式字符串 输出my_string.to_string()="\t"*/

printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));

/*释放资源*/

json_object_put(my_string);

3.3 JSON对象的操作

Int json_object_is_type(struct json_object * this, enum json_type type)

说明:

检查json_object是json的某个类型

参数:

this: json_object 实例

type: json_type_boolean,json_type_double, json_type_int, json_type_object, json_type_array, json_type_string

enum json_type json_object_get_type(struct json_object * this )

说明:

得到json_object的类型。

参数:

this – json对象

char * json_object_to_json_string(struct json_object * this)

说明:

将json_object内容转换json格式字符串,其中可能含有转义符。

参数:

this – json对象

返回值:

Json格式字符串

void json_object_object_add(struct json_object* obj, char *key, struct json_object *val);

说明:

添加个对象域到json对象中

参数:

Obj – json对象

key – 域名字

val – json值对象

void json_object_object_del(struct json_object* obj, char *key);

说明:

删除key值json对象

参数:

ob j – json对象

key – 域名字

int json_object_array_length(struct json_object *obj);

说明:

得到json对象数组的长度。

参数:

ob j – json数组值对象

extern int json_object_array_add(struct json_object *obj,

struct json_object *val);

说明:

添加一元素在json对象数组末端

参数:

ob j – json数组值对象

val – json值对象

*

int json_object_array_put_idx(struct json_object *obj, int idx,

struct json_object *val);

说明:

在指定的json对象数组下标插入或替换一个json对象元素。

参数:

ob j – json数组值对象

val – json值对象

idx – 数组下标

struct json_object * json_object_array_get_idx(struct json_object * json_array,int i);

说明:

从数组中,按下标取JSON值对象。

参数:

json_array – json 数组类型对象

i – 数组下标位置

定义宏 json_object_object_foreach(obj,key,val)

说明:

遍历json对象的key和值 (key, val默认参数不变)

样例片段:

/*创建个空json对象值数组类型*/

my_array = json_object_new_array();

/*添加json值类型到数组中*/

json_object_array_add(my_array, json_object_new_int(1));

json_object_array_add(my_array, json_object_new_int(2));

json_object_array_add(my_array, json_object_new_int(3));

json_object_array_put_idx(my_array, 4, json_object_new_int(5));

printf("my_array=\n");

for(i=0; i < json_object_array_length(my_array); i++) {

struct json_object *obj = json_object_array_get_idx(my_array, i);

printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));

}

printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));

my_object = json_object_new_object();

/*添加json名称和值到json对象集合中*/

json_object_object_add(my_object, "abc", json_object_new_int(12));

json_object_object_add(my_object, "foo", json_object_new_string("bar"));

json_object_object_add(my_object, "bool0", json_object_new_boolean(0));

json_object_object_add(my_object, "bool1", json_object_new_boolean(1));

json_object_object_add(my_object, "baz", json_object_new_string("bang"));

/*同样的key 添加会替换掉*/

json_object_object_add(my_object, "baz", json_object_new_string("fark"));

json_object_object_del(my_object, "baz");

/*添加数组集合到json对象中*/

json_object_object_add(my_object, "arr", my_array);

printf("my_object=\n");

/*遍历json对象集合*/

json_object_object_foreach(my_object, key, val) {

printf("\t%s: %s\n", key, json_object_to_json_string(val));

}

json_object_put(my_object);

4.    JSON实例开发

4.1 样例1

#include <stdio.h>

#include <stdlib.h>

#include <stddef.h>

#include <string.h>

#include "json.h"

int main(int argc, char **argv)

{

struct json_tokener *tok;

struct json_object *my_string, *my_int, *my_object, *my_array;

struct json_object *new_obj;

int i;

my_string = json_object_new_string("\t");

/*输出 my_string=   */

printf("my_string=%s\n", json_object_get_string(my_string));

/*转换json格式字符串 输出my_string.to_string()="\t"*/

printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));

/*释放资源*/

json_object_put(my_string);

my_string = json_object_new_string("\\");

printf("my_string=%s\n", json_object_get_string(my_string));

printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));

json_object_put(my_string);

my_string = json_object_new_string("foo");

printf("my_string=%s\n", json_object_get_string(my_string));

printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));

my_int = json_object_new_int(9);

printf("my_int=%d\n", json_object_get_int(my_int));

printf("my_int.to_string()=%s\n", json_object_to_json_string(my_int));

/*创建个空json对象值数组类型*/

my_array = json_object_new_array();

/*添加json值类型到数组中*/

json_object_array_add(my_array, json_object_new_int(1));

json_object_array_add(my_array, json_object_new_int(2));

json_object_array_add(my_array, json_object_new_int(3));

json_object_array_put_idx(my_array, 4, json_object_new_int(5));

printf("my_array=\n");

for(i=0; i < json_object_array_length(my_array); i++) {

struct json_object *obj = json_object_array_get_idx(my_array, i);

printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));

}

printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));

my_object = json_object_new_object();

/*添加json名称和值到json对象集合中*/

json_object_object_add(my_object, "abc", json_object_new_int(12));

json_object_object_add(my_object, "foo", json_object_new_string("bar"));

json_object_object_add(my_object, "bool0", json_object_new_boolean(0));

json_object_object_add(my_object, "bool1", json_object_new_boolean(1));

json_object_object_add(my_object, "baz", json_object_new_string("bang"));

/*同样的key 添加会替换掉*/

json_object_object_add(my_object, "baz", json_object_new_string("fark"));

json_object_object_del(my_object, "baz");

printf("my_object=\n");

/*遍历json对象集合*/

json_object_object_foreach(my_object, key, val) {

printf("\t%s: %s\n", key, json_object_to_json_string(val));

}

printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object));

/*对些不规则的串做了些解析测试*/

new_obj = json_tokener_parse("\"\003\"");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("/* hello */\"foo\"");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("// hello\n\"foo\"");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("null");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("True");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("12");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("12.3");

/*得到json double类型

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[\"\\n\"]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[\"\\nabc\\n\"]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[null]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[false]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{}");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

new_obj = json_tokener_parse("{ foo }");

if(is_error(new_obj)) printf("got error as expected\n");

new_obj = json_tokener_parse("foo");

if(is_error(new_obj)) printf("got error as expected\n");

new_obj = json_tokener_parse("{ \"foo");

if(is_error(new_obj)) printf("got error as expected\n");

/* test incremental parsing */

tok = json_tokener_new();

new_obj = json_tokener_parse_ex(tok, "{ \"foo", 6);

if(is_error(new_obj)) printf("got error as expected\n");

new_obj = json_tokener_parse_ex(tok, "\": {\"bar", 8);

if(is_error(new_obj)) printf("got error as expected\n");

new_obj = json_tokener_parse_ex(tok, "\":13}}", 6);

printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

json_object_put(new_obj);

json_tokener_free(tok);

json_object_put(my_string);

json_object_put(my_int);

json_object_put(my_object);

json_object_put(my_array);

/*如果前面没有添加到对象中, 必须显示释放,

如果添加到对象中,已经释放对象,则无需调用, 在这务必小心,否则很容易内存泄漏*/

return 0;

}

输出结果:

my_string=

my_string.to_string()="\t"

my_string=\

my_string.to_string()="\\"

my_string=foo

my_string.to_string()="foo"

my_int=9

my_int.to_string()=9

my_array=

[0]=1

[1]=2

[2]=3

[3]=null

[4]=5

my_array.to_string()=[ 1, 2, 3, null, 5 ]

my_object=

abc: 12

foo: "bar"

bool0: false

bool1: true

my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }

new_obj.to_string()="\u0003"

new_obj.to_string()="foo"

new_obj.to_string()="foo"

new_obj.to_string()="ABC"

new_obj.to_string()=null

new_obj.to_string()=true

new_obj.to_string()=12

new_obj.to_string()=12.300000

new_obj.to_string()=[ "\n" ]

new_obj.to_string()=[ "\nabc\n" ]

new_obj.to_string()=[ null ]

new_obj.to_string()=[ ]

new_obj.to_string()=[ false ]

new_obj.to_string()=[ "abc", null, "def", 12 ]

new_obj.to_string()={ }

new_obj.to_string()={ "foo": "bar" }

new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }

new_obj.to_string()={ "foo": [ null, "foo" ] }

new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }

got error as expected

got error as expected

got error as expected

new_obj.to_string()={ "foo": { "bar": 13 } }

备注

Json-c-0.8版本对0.7版本做的更新:

* 添加va_end 给指针至NULL 增加程序健壮性

* 添加宏使得能够编译出调试代码

* 解决个bug 在指数中使用大写字母E

* 添加 stddef.h 头文件

* 允许编译json-c 使用-Werror

json-c开发指南的更多相关文章

  1. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  2. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

  3. nodejs开发指南读后感

    nodejs开发指南读后感 阅读目录 使用nodejs创建http服务器; supervisor的使用及nodejs常见的调式代码命令了解; 了解Node核心模块; ejs模板引擎 Express 理 ...

  4. jQuery MiniUI 开发指南+API组件参考手册

    jQuery MiniUI 开发指南 本文档将逐步的讲解jQuery MiniUI的方方面面,从此您将踏上jQuery MiniUI的深入探索之旅.                 1.Hello M ...

  5. ECSHOP二次开发指南

    ECSHOP二次开发指南 发布时间:2013-05-28 12:47:00   来源:   评论:0 点击: 次 [字号:大 中 小] QQ空间新浪微博腾讯微博人人网豆瓣网百度空间百度搜藏开心网复制更 ...

  6. curl网站开发指南

    我一向以为,curl只是一个编程用的函数库. 最近才发现,这个命令本身,就是一个无比有用的网站开发工具,请看我整理的它的用法. =================================== ...

  7. Knockout应用开发指南(完整版) 目录索引

    http://learn.knockoutjs.com/  所有示例和代码都在在上面直接运行预览 注意:因为它用了google的cdn加速,所要要用代_理+_翻_墙才能正常加载 使用Knockout有 ...

  8. Knockout应用开发指南 第九章:高级应用举例

    原文:Knockout应用开发指南 第九章:高级应用举例 1   Contacts editor 这个例子和微软为演示jQuery Data Linking Proposal例子提供的例子一样的提供的 ...

  9. Knockout应用开发指南 第七章:Mapping插件

    原文:Knockout应用开发指南 第七章:Mapping插件 Mapping插件 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些 ...

  10. Knockout应用开发指南 第三章:绑定语法(1)

    原文:Knockout应用开发指南 第三章:绑定语法(1) 第三章所有代码都需要启用KO的ko.applyBindings(viewModel);功能,才能使代码生效,为了节约篇幅,所有例子均省略了此 ...

随机推荐

  1. Solr相似度算法一:Lucene TF-IDF 相关性算分公式

    Lucene在进行关键词查询的时候,默认用TF-IDF算法来计算关键词和文档的相关性,用这个数据排序 TF:词频,IDF:逆向文档频率,TF-IDF是一种统计方法,或者被称为向量空间模型,名字听起来很 ...

  2. 基于docker创建的Jenkins,settings.xml文件放在哪里

    如果运行容器时挂载目录如下 启动容器 docker run -itd -p 8080:8080 -p 50000:50000 --name jenkins --privileged=true  --r ...

  3. 用pillow和 opencv做透明通道的两图混全(blend)

    from PIL import Image as image foreground = image.open("donkey.png") background = image.op ...

  4. Cesium Language (CZML) 入门1 — CZML Structure(CZML的结构)

    原文:https://github.com/AnalyticalGraphicsInc/cesium/wiki/CZML-Structure CZML是一种用来描述动态场景的JSON架构的语言,主要用 ...

  5. 用MVC5+EF6+WebApi 做一个小功能(一)开场挖坑,在线答题系统

    从哪开始说呢,这几年微软的技术一直在变,像是牟足了劲要累死所有的NET程序员,从WebForm到MVC到现在MPA.SPA .Razor单页,从net2.0一直走到现在.net4.6.2,后面还有一个 ...

  6. VS2015 IIS Express 无法启动 解决办法(转)

    因为安装各种乱七八糟的软件,然后不小心把IIS Express卸载掉了,网上下载了一个IIS Express 7,安装之后本地使用VS 2015无法启动调试,F5 无法启动IIS, 再次F5调试,没有 ...

  7. 关于CocoaPods添加第三方库造成项目崩溃

    在很多时候,我们接手了别人的代码,项目中已经使用cocoapods,但是再想通过pods添加第三方库时会造成崩溃,如果你没备份项目的话那你就悲催了,幸好当初用了git了,不然又够忙乎的了. 好,回到正 ...

  8. CTF 介绍及杂项

    CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式.CTF起源于1996年DEFCON全球黑客大会,以代替之前黑客们通过 ...

  9. Ubuntu下实现socks代理转http代理

    代理(英语:Proxy),也称网络代理,是一种特殊的网络服务,允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接.一些网关.路由器等网络设备具备网络代理功能. ...

  10. Leetcode 98 验证二叉搜索树 Python实现

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...