Not Only Algorithm,不仅仅是算法,关注数学、算法、数据结构、程序员笔试面试以及一切涉及计算机编程之美的内容 。。
你的位置:NoAlGo博客 » 程序设计 » ,

CJSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它易于人阅读和编写,同时也方便机器解析和生成,成为一种理想的数据交换语言。
CJSON是一个用c写的JSON解析器,它非常小巧,只有单个文件,使用起来非常方便,本文将简单介绍CJSON的使用方法。

JSON

JSON的详细介绍可以参考:http://www.json.org/。其语法是JavaScript语法的子集,可以理解成无序的、可嵌套的key-value键值对集合,这些key-value键值对是以结构体或数组的形式来组织的。

JSON的数据包括以下类型:

  • 对象(object)是一个无序的key/value对集合。一个对象以“{”(左大括号)开始,“}”(右大括号)结束,每个key后跟一个“:”(冒号),key/value对之间使用“,”(逗号)分隔。
  • 数组(array)是值的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束,值之间使用“,”(逗号)分隔。
  • 值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
  • 字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。 字符串与C或者Java的字符串非常相似。
  • 数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

JSON结构简单来说就是对象和数组,通过这两种结构可以表示各种复杂的结构。

  • 对象表示为“{}”括起来的内容,数据结构为{key1:value1, key2:value2, …}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,这个属性值的类型可以是数字、字符串、数组、对象几种。
  • 数组表示为“[]”括起来的内容,数据结构为 ["value1", "value2", "value3", ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

下面是一个简单的JSON数据。注意,school的名称是加了双引号的S。

{
    "school": "school \"S\"",
    "students": [
        {"name": "A", "age": 10},
        {"name": "B", "age": 20}
    ]
}

XML和JSON都使用结构化方法来标记数据,总的来说,JSON格式取代了XML给网络传输带来了很大的便利,但是却没有了XML的一目了然。

  • 在语法上,JSON具有简易的语法,而XML具有规范的标签形式,而二者都具有良好的扩展性。不过JSON在Javascript主场作战,可以存储Javascript复合对象,有着xml不可比拟的优势。
  • 在编码上,二者均有丰富的编码工具,就难度来说,xml简单一些,不过写出来的字符JSON明显较少,因为xml包含很多重复的标记字符。
  • 在解码上,XML的解析方式有两种,一是通过文档模型解析,即通过父标签索引出一组标记,但是要预先知道文档结构,无法进行通用的封装;一是通过递归遍历节点进行解析,不过解析出来的数据仍旧是形式各异,往往也不能满足预先的要求。JSON也是如此,如果预先知道JSON的结构,可以很方便地解析;而如果不知道JSON的结构,那么解析工作将费时费力,代码变得冗余拖沓,结果不尽人意。但是前台开发人员可以使用json.js中的toJSONString()看到JSON的字符串结构,对JSON的结构有所了解然后再操作JSON。
  • 在有效数据率上,JSON作为数据包格式传输的时候具有更高的效率,因为JSON不像XML那样需要有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输压力。

CJSON

CJSON是轻量级的JSON解析器,非常方便使用,其下载地址为:http://cjson.sourceforge.net/
整个CJSON只有一个.h文件盒一个.c文件,代码量只有数百行,使用时只需简单地把cJSON.h头文件include进来,然后把cJSON.c加入到工程中即可。其提供的API函数含义非常清楚,根据名字及参数即可知道其提供的功能,这里不仔细讨论每个API的使用方法,相信通过简单的例子即可快速掌握。另外通过阅读自带的README帮助文档和test.c测试程序也可以获得大量信息。

下面以前面的JSON数据为例,说明如何使用CJSON进行解析。这里我们输入JSON文件的路径,读取JSON数据的内容,假设已经知道了JSON数据的格式,然后直接读取相应的节点的数值。注意JSON会自动帮我们申请需要的内存空间,所以不用的时候需要手动释放

void parseFile(char *fname)
{
	FILE *file = fopen(fname, "rb");

	//获取文件长度并申请对应内存空间
	fseek(file, 0, SEEK_END);
	int len = ftell(file);
	char *text = (char *) malloc(len + 1);

	fseek(file, 0, SEEK_SET);
	fread(text, 1, len, file);
	fclose(file);

	cJSON *json = cJSON_Parse(text);
	if (!json) 
	{
		printf("Error before: [%s]\n", cJSON_GetErrorPtr());
		return;
	}

	//获取学校名称
	cJSON *school = cJSON_GetObjectItem(json, "school");
	if (school)
	{
		char *schoolname = school->valuestring;
		printf("class: %s\n", schoolname);
	}

	//获取学生信息
	cJSON *students = cJSON_GetObjectItem(json, "students");
	if (students)
	{
		int cnt = cJSON_GetArraySize(students);
		for (int i = 0; i < cnt; i++)
		{
			cJSON *pArrayItem = cJSON_GetArrayItem(students, i);
			char *name = cJSON_GetObjectItem(pArrayItem, "name")->valuestring;
			int age = cJSON_GetObjectItem(pArrayItem, "age")->valueint;
			printf("student %d: name: %s age: %d\n", i, name, age);
		}
	}

	cJSON_Delete(json);
}

除了读取已有的JSON数据,还可以根据需要生产JSON格式的数据,然后保存或通过网络进行传输。下面讲产生前面例子的JSON数据并在屏幕上进行打印,主要是从根节点出发逐个生成需要的节点,最终得到完整的JSON数据结构,通过print函数打印出其文本形式,另外可以简单地改成写入文本来生产对应的JSON文件。

void create()
{
	cJSON *root = cJSON_CreateObject();

	cJSON *classname = cJSON_CreateString("\"S\"");
	cJSON_AddItemToObject(root, "school", classname);

	cJSON *students = cJSON_CreateArray();
	cJSON_AddItemToObject(root, "students", students);

	cJSON *student1 = cJSON_CreateObject();
	cJSON_AddStringToObject(student1, "name", "A");
	cJSON_AddNumberToObject(student1, "age", 10);
	cJSON_AddItemToArray(students, student1);

	cJSON *student2 = cJSON_CreateObject();
	cJSON_AddStringToObject(student2, "name", "A");
	cJSON_AddNumberToObject(student2, "age", 10);
	cJSON_AddItemToArray(students, student2);

	char *out = cJSON_Print(root);
	printf("%s\n", out);
	free(out);

	cJSON_Delete(root);
}

下面是一个简单的测试主程序。

int main(int argc, const char * argv[])
{
	printf("解析Json文件:\n");
	parseFile("myJson.txt");
	printf("\n创建Json文件\n");
	create();

	/*运行结果为*****************
	解析Json文件:
	class: school "S"
	student 0: name: A age: 10
	student 1: name: B age: 20

	创建Json文件
	{
			"school":       "\"S\"",
			"students":     [{
							"name": "A",
							"age":  10
					}, {
							"name": "A",
							"age":  10
					}]
	}
	****************************/
}
上一篇: 下一篇:
  1. #广东硅谷学院#学好IT好就业选硅谷IT,学技能拿文凭事半功倍,紧跟专业教师一起冲浪IT行业。我们有建设学习型专业师资团队,教师领跑学生紧随其后。(QQ:800015777,电话0754-88989555)

我的博客

NoAlGo头像编程这件小事牵扯到太多的知识,很容易知其然而不知其所以然,但真正了不起的程序员对自己程序的每一个字节都了如指掌,要立足基础理论,努力提升自我的专业修养。

站内搜索

最新评论