当前位置:首页 > 公众号精选 > 码农爱学习

C语言开发中,你使用过cJSON吗

在介绍cJSON之前,首先来认识一下JSON...

01

JSON是什么

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。

JSON 基本语法

  • 数据以key :value(名称/值) 的形式存在

  • 数据由逗号,分隔

  • 大括号{}保存对象

  • 中括号[]保存数组,数组可以包含多个对象

例如:

{ name : C Primer pluse, pages : 626 }

JSON值(value)的类型

/* cJSON Types: */#define cJSON_False 0#define cJSON_True 1#define cJSON_NULL 2#define cJSON_Number 3#define cJSON_String 4#define cJSON_Array 5#define cJSON_Object 6

逻辑值(true 或 false)

{"flag":true}

null

{"name":null}

NUMBER 数字(整数或浮点数)

{"pages":200, "price":35.00}

STRING 字符串(在双引号""中)

{"book":"C Primer pluse"}

ARRAY 数组(在中括号[]中)

[    {"name":"C Primer pluse", "author":"Stephen Prata"},    {"name":"C程序设计", "author":"谭浩强"},    {"name":"C陷阱与缺陷", "author":"Andrew Koenig"}]

OBJECT 对象(在大括号{}中)

{"name":"C Primer pluse", "author":"Stephen Prata"}

当然对象内部也可以是数组,如:

{    "books":[        {"name":"C Primer pluse", "author":"Stephen Prata"},        {"name":"C程序设计", "author":"谭浩强"},        {"name":"C陷阱与缺陷", "author":"Andrew Koenig"}      ]}

对象books内部是一个数组,该数组又包含了三个对象

02

cJSON又是个啥

cJSON是一个基于C的JSON解析库,这个库非常简短,源码内容只包含:一个cJSON.h头文件和一个cJSON.c源文件,支持JSON的解析和封装,需要调用时,只需要#include "cJSON.h"就可以使用了。

03

cJSON编程实例

例子1

先演示一个最简单的JSON数据,如何使用cJSON库来解析。

用于测试JSON数据,我们先用一个char型的字符串了保存,注意,由于JSON对象的key和value都需要使用引号(数值或逻辑型value除外),所以,使用C语言的字符串来保存JSON数据,在遇到引号时,要加反斜杠来转义。

解析JSON数据时,首先要调用cJSON_Parse()这个函数,将JSON数据解析为cJSON型的对象:

cJSON *srcJsonData = cJSON_Parse(jsonData);

然后就可以使用cJSON库中提供的各种函数来操作这个对象。比如 :

value = cJSON_GetObjectItem(srcJsonData,"name");

就是通过cJSON_GetObjectItem()来获取JSON数据中的一项数据,并通过指定key的方式来获取对应的value。

整个测试程序如下:

#include #include #include "cJSON.h"
void main(void){ char jsonData[] = "{\"name\":\"C Primer pluse\",\"pages\":626}";
cJSON *srcJsonData = cJSON_Parse(jsonData); if(!srcJsonData) { printf("Error:%s\r\n",cJSON_GetErrorPtr()); } else { /*获取Json数据的内容*/ cJSON *value; value = cJSON_GetObjectItem(srcJsonData,"name");/*通过key来获取value*/ if(value->type == cJSON_String)/*字符串型的value*/ { printf("书名:%s\r\n",value->valuestring); } value = cJSON_GetObjectItem(srcJsonData,"pages");/*通过key来获取value*/ if(value->type == cJSON_Number)/*数值型的value*/ { printf("页数:%d\r\n",value->valueint); } cJSON_Delete(srcJsonData); }}

运行结果:

书名:C Primer pluse
页数:626

--------------------------------
Process exited after 0.01452 seconds with return value 0
请按任意键继续. . .

例子2

上面是一个最基本的测试程序,JSON数据也是直接通过C语言的字符串保存的。

实际的使用中,JSON数据的内容较为庞大,再使用C语言的字符串来保存,则会及其麻烦(想想那一堆反斜杠)。

所以,一般都是使用文件的形式来保存JSON数据。

准备一个原始数据用于测试,如下面的data.txt:

{    "class":"C语言书籍",    "books":[{        "name":"C Primer pluse",        "author":"Stephen Prata",        "publishing":"人民邮电出版社"        },                {        "name":"C程序设计",        "author":"谭浩强",        "publishing":"清华大学出版社"        },                {        "name":"C陷阱与缺陷",        "author":"Andrew Koenig",        "publishing":"人民邮电出版社"        }]}

先来分析下这个JSON数据的结构:

  • 最外面的大括号,表示这个一个JSON对象

  • 对象里面有2个数据,key1是class,key2是books

  • books的value又是一个中括号表示的数组

  • 数组内又包含了3个对象,每个对象有3个数据,key1是name,key2是author,key3是publishing

解析这种JSON文件,使用要使用fopen()来打开这个文件:

FILE *fp = fopen("data.txt", "r");

这里还要使用fseek()和ftell()来计算文件的大小,目的是用于后面的分配内存时指定大小。

然后使用fread()将文件内存读入内存中分配的buf中:

fread(buf, fileSize, sizeof(char), fp);

接着,还是使用cJSON_Parse()将JSON数据解析为cJSON型的对象

cJSON *srcJsonData = cJSON_Parse(buf);

然后就可以使用cJSON库中提供的各种函数来操作这个对象了。

这次会用到cJSON_GetObjectItem()、cJSON_GetArrayItem()、cJSON_GetArraySize()、cJSON_Print()等函数。

注意是使用完cJSON_Print()后,要使用free()来释放。

具体的测试程序如下:

#include #include #include #include "cJSON.h"
void main(void){ /*打开JSON文件*/ FILE *fp = fopen("data.txt", "r"); if(fp == NULL) { return; }
/*计算文件大小*/ int fileSize; fseek(fp, 0, SEEK_END);/*先移到文件末尾*/ fileSize = ftell(fp);/*计算文件的大小*/ printf("fileSize: %d\r\n", fileSize); fseek(fp, 0, SEEK_SET);/*再移到文件开头*/
/*根据文件大小分配内存,并读取文件到内存*/ char *buf = (char *)malloc(fileSize * sizeof(char)); memset(buf, 0, fileSize); int ret = fread(buf, fileSize, sizeof(char), fp); if(ret == -1) { fclose(fp); return; } printf("%s\r\n",buf); fclose(fp);
/*把该字符串数据转成JSON数据*/ cJSON *srcJsonData = cJSON_Parse(buf); free(buf); if(srcJsonData == NULL) { printf("err\r\n"); return; }
cJSON *value; /*根据key值(class)获取对应的value*/ value = cJSON_GetObjectItem(srcJsonData, "class"); if(value == NULL)    { printf("GetObjectItem err\r\n"); cJSON_Delete(srcJsonData); return; }
/*把value转成字符串输出*/ char *data = cJSON_Print(value); printf("class = %s\r\n",data); free(data);

/*根据key值(books)获取对应的value*/ value = cJSON_GetObjectItem(srcJsonData, "books"); if(value == NULL) { printf("GetObjectItem err\r\n"); cJSON_Delete(srcJsonData); return; }
/*获取该数组对象的大小*/ int len = cJSON_GetArraySize(value); printf("books data: len=%d\r\n",len);
/*访问books中的每一项*/ int i = 0; for(i=0; i { /*先获取每一条信息*/ cJSON *tmpValue = cJSON_GetArrayItem(value,i); /*再获取每条信息中的具体内容*/ cJSON *nameValue = cJSON_GetObjectItem(tmpValue,"name"); cJSON *authorValue = cJSON_GetObjectItem(tmpValue,"author"); cJSON *publishValue = cJSON_GetObjectItem(tmpValue,"publishing"); if(nameValue == NULL || authorValue == NULL || publishValue == NULL) { printf("GetObjectItem err\r\n"); cJSON_Delete(srcJsonData); return; } /*打印出来*/ char *print1 = cJSON_Print(nameValue); char *print2 = cJSON_Print(authorValue); char *print3 = cJSON_Print(publishValue); printf("[%d] %s \t %s \t %s\r\n",i+1,print1,print2,print3); free(print1); free(print2); free(print3); } cJSON_Delete(srcJsonData);}

运行结果:

fileSize: 433
{
   "class":"C语言书籍",
   "books":[{
       "name":"C Primer pluse",
       "author":"Stephen Prata",
       "publishing":"人民邮电出版社"
      },

      {
       "name":"C程序设计",
       "author":"谭浩强",
       "publishing":"清华大学出版社"
      },

      {
       "name":"C陷阱与缺陷",
       "author":"Andrew Koenig",
       "publishing":"人民邮电出版社"
      }]
}
class = "C语言书籍"
books data: len=3
[1] "C Primer pluse"     "Stephen Prata"         "人民邮电出版社"
[2] "C程序设计"          "谭浩强"        "清华大学出版社"
[3] "C陷阱与缺陷"        "Andrew Koenig"         "人民邮电出版社"

--------------------------------
Process exited after 0.01578 seconds with return value 0
请按任意键继续. . .
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭