使用cJSON解析JSON字符串

来源:互联网 发布:网络推广绩效考核指标 编辑:程序博客网 时间:2024/04/29 12:22
  1. 解析JSON格式
    还是在Linux下,使用C语言编程,先实现读文件的功能,然后开始JSON字符串的解析。我们还是一步步来,先从简单的开始,万丈高楼起于平地嘛。
    1,下载源码;
    可以从如下网站来下载:https://sourceforge.net/projects/cjson/ 。
    2,包含cJSON的源码;
    下载下来,解压后,从里面找到两个文件(cJSON.c、cJSON.h),复制到我们的工程里面。只需在函数中包含头文件(#include “cJSON.h”),然后和cJSON.c一起编译即可使用。
    3,解析一个键值对;
    首先是一个简单的键值对字符串,要解析的目标如下:
    {“firstName”:”Brett”}
    要进行解析,也就是要分别获取到键与值的内容。我们很容易就能看出键为firstName,值为Brett,可是,使用cJSON怎么解析呢?
    对于这个简单的例子,只需要调用cJSON的三个接口函数就可以实现解析了,这三个函数的原型如下:
    cJSON*cJSON_Parse(const char *value);
    cJSON*cJSON_GetObjectItem(cJSON *object,const char *string);
    voidcJSON_Delete(cJSON *c);
    下面按解析过程来描述一次:
    (1) 首先调用cJSON_Parse()函数,解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包。使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。
    cJSON*root=cJSON_Parse(json_string);
    (2) 调用cJSON_GetObjectItem()函数,可从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。
    cJSON*item=cJSON_GetObjectItem(root,”firstName”);
    (3) 如果需要使用cJSON结构体中的内容,可通过cJSON结构体中的valueint和valuestring取出有价值的内容(即键的值)
    本例子中,我们直接访问 item->valuestring 就获取到 “Brett” 的内容了。
    (4) 通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
    cJSON_Delete(root);
    这样就完成了一次cJSON接口调用,实现了解析工作。使用起来其实也很简单的啊,呵呵。
    4,解析一个结构体;
    接下来,我们来个复杂一点的,解析一个结构体,要解析的目标如下:
    {
    “person”:
    {
    “firstName”:”z”,
    “lastName”:”jadena”,
    “email”:”jadena@126.com”,
    “age”:8,
    “height”:1.17
    }
    }
    看起来比一个键值对复杂多了,我们又需要学习新的接口函数了吗?
    答案是不需要!
    还是那三个函数就可以了。当然,解析的步骤要复杂一些了,下面我按解析过程来描述一次:
    (1)根据JSON串中的对象,我们定义一个相应的结构体如下:
    typedefstruct
    {
    char firstName[32];
    char lastName[32];
    char email[64];
    int age;
    float height;
    } PERSON;
    具体的对应关系,一目了然,我就不罗嗦了。让我们直奔主题,解析!
    (2)还是调用cJSON_Parse()函数,解析JSON数据包。
    cJSON*root=cJSON_Parse(json_string);
    (3)调用一次cJSON_GetObjectItem()函数,获取到对象person。
    cJSON *object=cJSON_GetObjectItem(root,”person”);
    (4)对我们刚取出来的对象person,多次调用cJSON_GetObjectItem()函数,来获取对象的成员。此时要注意,不同的成员,访问的方法不一样:
    cJSON*item;
    PERSONperson;
    item=cJSON_GetObjectItem(object,”firstName”);
    memcpy(person.firstName,item->valuestring,strlen(item->valuestring));
    item=cJSON_GetObjectItem(object,”lastName”);
    memcpy(person.lastName,item->valuestring,strlen(item->valuestring));
    item=cJSON_GetObjectItem(object,”email”);
    memcpy(person.email,item->valuestring,strlen(item->valuestring));
    item=cJSON_GetObjectItem(object,”age”);
    person.age=item->valueint;
    item=cJSON_GetObjectItem(object,”height”);
    person.height=item->valuedouble;
    这样,就获取到了对象的全部内容了。
    (5) 通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
    cJSON_Delete(root);
    至此,我们就使用cJSON接口完成了基于结构体的解析工作。
    5,解析结构体数组的JSON串;
    最后,我们来个更复杂一些的,来解析一个数组,并且数组的成员是结构体!要解析的JSON串如下:
    {
    “people”:[
    {“firstName”:”z”,”lastName”:”Jason”,”email”:”bbbb@126.com”,”height”:1.67},
    {“lastName”:”jadena”,”email”:”jadena@126.com”,”age”:8,”height”:1.17},
    {“email”:”cccc@126.com”,”firstName”:”z”,”lastName”:”Juliet”,”age”:36,”height”:1.55}
    ]
    }
    此时,我们真的又需要学习新的接口了,一个是获取数组长度,一个是取数组成员,函数原型如下:
    int cJSON_GetArraySize(cJSON *array);
    cJSON*cJSON_GetArrayItem(cJSON *array,int item);
    由于前面已经实现了结构体的解析,这里我们只需要关注下数组的相关调用即可。
    (1)调用cJSON_Parse()函数,解析JSON数据包。
    (2)调用一次cJSON_GetObjectItem()函数,获取到数组people。
    (3)对我们刚取出来的数组people,调用cJSON_GetArraySize()函数,来获取数组中对象的个数。然后,多次调用cJSON_GetArrayItem()函数,逐个读取数组中对象的内容。
    (4)通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。
    这样,我们就使用cJSON接口完成了结构体数组的解析工作。
    详细代码见后文附带例程。
    说明:
    本文所附带例程,实现了结构体数组的解析,只是一个学习之作,对于初学JSON使用cJSON接口的同学,可以有些借鉴参考的作用。

附带例程:

    [cpp]#include <stdio.h>  #include <string.h>  #include <sys/types.h>  #include <stdlib.h>  #include <unistd.h>  #include "cJSON.h"  typedef struct  {      int id;      char firstName[32];      char lastName[32];      char email[64];      int age;      float height;  }people;  void dofile(char *filename);/* Read a file, parse, render back, etc. */  int main(int argc, char **argv)  {  //  dofile("json_str1.txt");  //  dofile("json_str2.txt");      dofile("json_str3.txt");      return 0;  }  //parse a key-value pair  int cJSON_to_str(char *json_string, char *str_val)  {      cJSON *root=cJSON_Parse(json_string);      if (!root)      {          printf("Error before: [%s]\n",cJSON_GetErrorPtr());          return -1;      }      else      {          cJSON *item=cJSON_GetObjectItem(root,"firstName");          if(item!=NULL)          {              printf("cJSON_GetObjectItem: type=%d, key is %s, value is %s\n",item->type,item->string,item->valuestring);              memcpy(str_val,item->valuestring,strlen(item->valuestring));          }          cJSON_Delete(root);      }      return 0;  }  //parse a object to struct  int cJSON_to_struct(char *json_string, people *person)  {      cJSON *item;      cJSON *root=cJSON_Parse(json_string);      if (!root)      {          printf("Error before: [%s]\n",cJSON_GetErrorPtr());          return -1;      }      else      {          cJSON *object=cJSON_GetObjectItem(root,"person");          if(object==NULL)          {              printf("Error before: [%s]\n",cJSON_GetErrorPtr());              cJSON_Delete(root);              return -1;          }          printf("cJSON_GetObjectItem: type=%d, key is %s, value is %s\n",object->type,object->string,object->valuestring);          if(object!=NULL)          {              item=cJSON_GetObjectItem(object,"firstName");              if(item!=NULL)              {                  printf("cJSON_GetObjectItem: type=%d, string is %s, valuestring=%s\n",item->type,item->string,item->valuestring);                  memcpy(person->firstName,item->valuestring,strlen(item->valuestring));              }              item=cJSON_GetObjectItem(object,"lastName");              if(item!=NULL)              {                  printf("cJSON_GetObjectItem: type=%d, string is %s, valuestring=%s\n",item->type,item->string,item->valuestring);                  memcpy(person->lastName,item->valuestring,strlen(item->valuestring));              }              item=cJSON_GetObjectItem(object,"email");              if(item!=NULL)              {                  printf("cJSON_GetObjectItem: type=%d, string is %s, valuestring=%s\n",item->type,item->string,item->valuestring);                  memcpy(person->email,item->valuestring,strlen(item->valuestring));              }              item=cJSON_GetObjectItem(object,"age");              if(item!=NULL)              {                  printf("cJSON_GetObjectItem: type=%d, string is %s, valueint=%d\n",item->type,item->string,item->valueint);                  person->age=item->valueint;              }              else              {                  printf("cJSON_GetObjectItem: get age failed\n");              }              item=cJSON_GetObjectItem(object,"height");              if(item!=NULL)              {                  printf("cJSON_GetObjectItem: type=%d, string is %s, valuedouble=%f\n",item->type,item->string,item->valuedouble);                  person->height=item->valuedouble;              }          }          cJSON_Delete(root);      }      return 0;  }  //parse a struct array  int cJSON_to_struct_array(char *text, people worker[])  {      cJSON *json,*arrayItem,*item,*object;      int i;      json=cJSON_Parse(text);      if (!json)      {          printf("Error before: [%s]\n",cJSON_GetErrorPtr());      }      else      {          arrayItem=cJSON_GetObjectItem(json,"people");          if(arrayItem!=NULL)          {              int size=cJSON_GetArraySize(arrayItem);              printf("cJSON_GetArraySize: size=%d\n",size);              for(i=0;i<size;i++)              {                  printf("i=%d\n",i);                  object=cJSON_GetArrayItem(arrayItem,i);                  item=cJSON_GetObjectItem(object,"firstName");                  if(item!=NULL)                  {                      printf("cJSON_GetObjectItem: type=%d, string is %s\n",item->type,item->string);                      memcpy(worker[i].firstName,item->valuestring,strlen(item->valuestring));                  }                  item=cJSON_GetObjectItem(object,"lastName");                  if(item!=NULL)                  {                      printf("cJSON_GetObjectItem: type=%d, string is %s, valuestring=%s\n",item->type,item->string,item->valuestring);                      memcpy(worker[i].lastName,item->valuestring,strlen(item->valuestring));                  }                  item=cJSON_GetObjectItem(object,"email");                  if(item!=NULL)                  {                      printf("cJSON_GetObjectItem: type=%d, string is %s, valuestring=%s\n",item->type,item->string,item->valuestring);                      memcpy(worker[i].email,item->valuestring,strlen(item->valuestring));                  }                  item=cJSON_GetObjectItem(object,"age");                  if(item!=NULL)                  {                      printf("cJSON_GetObjectItem: type=%d, string is %s, valueint=%d\n",item->type,item->string,item->valueint);                      worker[i].age=item->valueint;                  }                  else                  {                      printf("cJSON_GetObjectItem: get age failed\n");                  }                  item=cJSON_GetObjectItem(object,"height");                  if(item!=NULL)                  {                      printf("cJSON_GetObjectItem: type=%d, string is %s, value=%f\n",item->type,item->string,item->valuedouble);                      worker[i].height=item->valuedouble;                  }              }          }          for(i=0;i<3;i++)          {              printf("i=%d, firstName=%s,lastName=%s,email=%s,age=%d,height=%f\n",                      i,                      worker[i].firstName,                      worker[i].lastName,                      worker[i].email,                      worker[i].age,                      worker[i].height);          }          cJSON_Delete(json);      }      return 0;  }  // Read a file, parse, render back, etc.  void dofile(char *filename)  {      FILE *f;      int len;      char *data;      f=fopen(filename,"rb");      fseek(f,0,SEEK_END);      len=ftell(f);      fseek(f,0,SEEK_SET);      data=(char*)malloc(len+1);      fread(data,1,len,f);      fclose(f);      printf("read file %s complete, len=%d.\n",filename,len);  //  char str_name[40];  //  int ret = cJSON_to_str(data, str_name);  //  people person;  //  int ret = cJSON_to_struct(data, &person);      people worker[3]={{0}};      cJSON_to_struct_array(data, worker);      free(data);  }  
原创粉丝点击