JSON-C语言开发指南
摘自:https://www.cnblogs.com/luoluo1619/p/13925254.html
一、前言
本文档是基于json-c库对数据交换进行开发所编写的开发指南,及详细解释json-c库中常用api。 适用于开发人员使用c语言对json的编程
(注:此文档json-c库版本为0.8——json-c-0.8)
二、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)、true、false、 null、对象(object)或者数组(array)。
这些结构可以嵌套。
字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。
一个字符(character)即一个单独的字符串(character string)。
字符串(string)与C或者Java的字符串非常相似。
数值(number)也与C或者Java的数值非常相似。
除去未曾使用的八进制与十六进制格式。除去一些编码细节。
三、JSON库函数说明
3.1 JSON对象的生成
1 Json对象的类型: 2 json_type_object, “名称/值”对的集合 3 4 /* Json对象的值类型 */ 5 json_type_boolean, 6 json_type_double, 7 json_type_int, 8 json_type_array, “值”的集合 9 json_type_string 10 11 /* 创建个空的json_type_object类型JSON对象 */ 12 struct json_object * json_object_new_object(); 13 14 /* 创建个json_type_boolean值类型json对象 */ 15 struct json_object* json_object_new_boolean(boolean b); 16 17 /* 从json对象中boolean值类型得到boolean值 */ 18 boolean json_object_get_boolean(struct json_object *obj); 19 20 同样: 21 struct json_object* json_object_new_int(int i) 22 int json_object_get_int(struct json_object *this) 23 struct json_object* json_object_new_double(double d) 24 double json_object_get_double(struct json_object *this) 25 struct json_object* json_object_new_string(char *s) 26 char* json_object_get_string(struct json_object *this) 27 28 29 /* 创建个空的json_type_array类型JSON数组值对象。 */ 30 struct json_object * json_object_new_array(); 31 32 /* 由str里的JSON字符串生成JSON对象,str是son_object_to_json_string() 生成的。 33 * 参数: 34 * str – json字符串 35 */ 36 struct json_object * json_tokener_parse(char *str); // 37 38 /* 从json中按名字取一个对象。 39 * 参数: 40 * json – json对象 41 * name - json域名字 42 */ 43 struct json_object * json_object_object_get(struct json_object * json,char *name);
3.2 JSON对象的释放
1 /* 增加对象引用计数。使用c库最关心的是内存谁来分配, 谁来释放. 2 * jsonc的内存管理方式, 是基于引用计数的内存树(链), 3 * 如果把一个struct json_object 对象a, add到另一个对象b上, 4 * 就不用显式的释放(json_object_put) a了, 相当于把a挂到了b的对象树上, 5 * 释放b的时候, 就会释放a. 当a即add到b上, 又add到对象c上时会导致a被释放两次(double free), 6 * 这时可以增加a的引用计数(调用函数json_object_get(a)), 7 * 这时如果先释放b, 后释放c, 当释放b时, 并不会真正的释放a, 而是减少a的引用计数为1, 然后释放c时, 才真正释放a. 8 * 参数: 9 * this – json对象 10 */ 11 struct json_object * * json_object_get(struct json_object * this) 12 13 /* 减少对象引用次数一次,当减少到0就释放(free)资源 14 * this – json对象 15 */ 16 void json_object_put(struct json_object * this) 17 18 19 /* 样例片段:*/ 20 my_string = json_object_new_string("\t"); /*输出 my_string= */ \t(table键) 21 printf("my_string=%s\n", json_object_get_string(my_string)); 22 23 /*转换json格式字符串 输出my_string.to_string()="\t"*/ 24 printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); 25 26 /*释放资源*/ 27 json_object_put(my_string);
3.3 JSON对象的操作
1 /* 检查json_object是json的某个类型 2 * 参数: 3 * this: json_object 实例 4 * type: json_type_boolean,json_type_double, json_type_int, json_type_object, json_type_array, json_type_string 5 */ 6 int json_object_is_type(struct json_object * this, enum json_type type) 7 8 /* 得到json_object的类型。 9 * 参数: 10 * this – json对象 11 */ 12 enum json_type json_object_get_type(struct json_object * this ) 13 14 /* 将json_object内容转换json格式字符串,其中可能含有转义符。 15 * 参数: 16 * this – json对象 17 * 返回值: 18 * json格式字符串 19 */ 20 char * json_object_to_json_string(struct json_object * this) 21 22 /* 添加个对象域到json对象中 23 * 参数: 24 * obj – json对象 25 * key – 域名字 26 * val – json值对象 27 */ 28 void json_object_object_add(struct json_object* obj, char *key, struct json_object *val); 29 30 31 /* 删除key值json对象 32 * 参数: 33 * obj – json对象 34 * key – 域名字 35 */ 36 void json_object_object_del(struct json_object* obj, char *key); 37 38 /* 得到json对象数组的长度。 39 * 参数: 40 * obj – json数组值对象 41 */ 42 int json_object_array_length(struct json_object *obj); 43 44 /* 添加一元素在json对象数组末端 45 * 参数: 46 * obj – json数组值对象 47 * val – json值对象 48 */ 49 extern int json_object_array_add(struct json_object *obj, struct json_object *val); 50 51 /* 在指定的json对象数组下标插入或替换一个json对象元素。 52 * 参数: 53 * obj – json数组值对象 54 * val – json值对象 55 * idx – 数组下标 56 */ 57 int json_object_array_put_idx(struct json_object *obj, int idx, struct json_object *val); 58 59 60 /* 从数组中,按下标取JSON值对象。 61 * 参数: 62 * json_array – json 数组类型对象 63 * i – 数组下标位置 64 */ 65 struct json_object * json_object_array_get_idx(struct json_object * json_array,int i); 66 67 /* 定义宏。遍历json对象的key和值 (key, val默认参数不变)*/ 68 json_object_object_foreach(obj,key,val)
============================================
样例片段:
1 /*创建个空json对象值数组类型*/ 2 my_array = json_object_new_array(); 3 4 /*添加json值类型到数组中*/ 5 json_object_array_add(my_array, json_object_new_int(1)); 6 json_object_array_add(my_array, json_object_new_int(2)); 7 json_object_array_add(my_array, json_object_new_int(3)); 8 json_object_array_put_idx(my_array, 4, json_object_new_int(5)); 9 printf("my_array=\n"); 10 11 for(i=0; i < json_object_array_length(my_array); i++) { 12 struct json_object *obj = json_object_array_get_idx(my_array, i); 13 printf("\t[%d]=%s\n", i, json_object_to_json_string(obj)); 14 } 15 16 printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); 17 my_object = json_object_new_object(); 18 19 /*添加json名称和值到json对象集合中*/ 20 json_object_object_add(my_object, "abc", json_object_new_int(12)); 21 json_object_object_add(my_object, "foo", json_object_new_string("bar")); 22 json_object_object_add(my_object, "bool0", json_object_new_boolean(0)); 23 json_object_object_add(my_object, "bool1", json_object_new_boolean(1)); 24 json_object_object_add(my_object, "baz", json_object_new_string("bang")); 25 26 /*同样的key 添加会替换掉*/ 27 json_object_object_add(my_object, "baz", json_object_new_string("fark")); 28 json_object_object_del(my_object, "baz"); 29 30 /*添加数组集合到json对象中*/ 31 json_object_object_add(my_object, "arr", my_array); 32 printf("my_object=\n"); 33 34 /*遍历json对象集合*/ 35 json_object_object_foreach(my_object, key, val) { 36 printf("\t%s: %s\n", key, json_object_to_json_string(val)); 37 } 38 json_object_put(my_object);
四、 JSON实例开发
样例
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stddef.h> 4 #include <string.h> 5 #include "json.h" 6 7 int main(int argc, char **argv) 8 { 9 struct json_tokener *tok; 10 struct json_object *my_string, *my_int, *my_object, *my_array; 11 struct json_object *new_obj; 12 int i; 13 14 my_string = json_object_new_string("\t"); 15 16 /*输出 my_string= */ 17 printf("my_string=%s\n", json_object_get_string(my_string)); 18 19 /*转换json格式字符串 输出my_string.to_string()="\t"*/ 20 printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); 21 22 /*释放资源*/ 23 json_object_put(my_string); 24 25 my_string = json_object_new_string("\\"); 26 printf("my_string=%s\n", json_object_get_string(my_string)); 27 printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); 28 json_object_put(my_string); 29 30 my_string = json_object_new_string("foo"); 31 printf("my_string=%s\n", json_object_get_string(my_string)); 32 printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); 33 34 my_int = json_object_new_int(9); 35 printf("my_int=%d\n", json_object_get_int(my_int)); 36 printf("my_int.to_string()=%s\n", json_object_to_json_string(my_int)); 37 38 /*创建个空json对象值数组类型*/ 39 my_array = json_object_new_array(); 40 /*添加json值类型到数组中*/ 41 json_object_array_add(my_array, json_object_new_int(1)); 42 json_object_array_add(my_array, json_object_new_int(2)); 43 json_object_array_add(my_array, json_object_new_int(3)); 44 json_object_array_put_idx(my_array, 4, json_object_new_int(5)); 45 printf("my_array=\n"); 46 for(i=0; i < json_object_array_length(my_array); i++) { 47 struct json_object *obj = json_object_array_get_idx(my_array, i); 48 printf("\t[%d]=%s\n", i, json_object_to_json_string(obj)); 49 } 50 51 printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); 52 my_object = json_object_new_object(); 53 54 /*添加json名称和值到json对象集合中*/ 55 json_object_object_add(my_object, "abc", json_object_new_int(12)); 56 json_object_object_add(my_object, "foo", json_object_new_string("bar")); 57 json_object_object_add(my_object, "bool0", json_object_new_boolean(0)); 58 json_object_object_add(my_object, "bool1", json_object_new_boolean(1)); 59 json_object_object_add(my_object, "baz", json_object_new_string("bang")); 60 61 /*同样的key 添加会替换掉*/ 62 json_object_object_add(my_object, "baz", json_object_new_string("fark")); 63 json_object_object_del(my_object, "baz"); 64 65 printf("my_object=\n"); 66 /*遍历json对象集合*/ 67 json_object_object_foreach(my_object, key, val) { 68 printf("\t%s: %s\n", key, json_object_to_json_string(val)); 69 } 70 printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); 71 72 /*对些不规则的串做了些解析测试*/ 73 new_obj = json_tokener_parse("\"\003\""); 74 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 75 json_object_put(new_obj); 76 77 new_obj = json_tokener_parse("/* hello */\"foo\""); 78 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 79 json_object_put(new_obj); 80 81 new_obj = json_tokener_parse("// hello\n\"foo\""); 82 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 83 json_object_put(new_obj); 84 85 new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\""); 86 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 87 json_object_put(new_obj); 88 89 new_obj = json_tokener_parse("null"); 90 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 91 json_object_put(new_obj); 92 93 new_obj = json_tokener_parse("True"); 94 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 95 json_object_put(new_obj); 96 97 new_obj = json_tokener_parse("12"); 98 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 99 json_object_put(new_obj); 100 101 /*得到json double类型 102 new_obj = json_tokener_parse("12.3"); 103 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 104 json_object_put(new_obj); 105 106 new_obj = json_tokener_parse("[\"\\n\"]"); 107 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 108 json_object_put(new_obj); 109 110 111 new_obj = json_tokener_parse("[\"\\nabc\\n\"]"); 112 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 113 json_object_put(new_obj); 114 115 new_obj = json_tokener_parse("[null]"); 116 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 117 json_object_put(new_obj); 118 119 new_obj = json_tokener_parse("[]"); 120 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 121 json_object_put(new_obj); 122 123 new_obj = json_tokener_parse("[false]"); 124 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 125 json_object_put(new_obj); 126 127 new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]"); 128 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 129 json_object_put(new_obj); 130 131 new_obj = json_tokener_parse("{}"); 132 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 133 json_object_put(new_obj); 134 135 new_obj = json_tokener_parse("{ \"foo\": \"bar\" }"); 136 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 137 json_object_put(new_obj); 138 139 new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }"); 140 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 141 json_object_put(new_obj); 142 143 new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }"); 144 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 145 json_object_put(new_obj); 146 147 new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }"); 148 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 149 json_object_put(new_obj); 150 151 new_obj = json_tokener_parse("{ foo }"); 152 if(is_error(new_obj)) printf("got error as expected\n"); 153 new_obj = json_tokener_parse("foo"); 154 155 if(is_error(new_obj)) printf("got error as expected\n"); 156 new_obj = json_tokener_parse("{ \"foo"); 157 if(is_error(new_obj)) printf("got error as expected\n"); 158 /* test incremental parsing */ 159 tok = json_tokener_new(); 160 new_obj = json_tokener_parse_ex(tok, "{ \"foo", 6); 161 if(is_error(new_obj)) printf("got error as expected\n"); 162 new_obj = json_tokener_parse_ex(tok, "\": {\"bar", 8); 163 if(is_error(new_obj)) printf("got error as expected\n"); 164 new_obj = json_tokener_parse_ex(tok, "\":13}}", 6); 165 printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); 166 json_object_put(new_obj); 167 json_tokener_free(tok); 168 169 json_object_put(my_string); 170 json_object_put(my_int); 171 json_object_put(my_object); 172 json_object_put(my_array); 173 174 /*如果前面没有添加到对象中, 必须显示释放, 175 *如果添加到对象中,已经释放对象,则无需调用, 176 *在这务必小心,否则很容易内存泄漏*/ 177 178 return 0; 179 180 }
输出结果:
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 } }