JSON数据格式交换 C语言cJSON开源

来源:互联网 发布:windows登录密码忘记 编辑:程序博客网 时间:2024/06/06 01:41
1.JSON官方http://www.json.org/
里面有很多JSON解析工具,分别用不同编程语言实现,比如C语言下流行的cJSON,除此之外还有很多C版本的工具,其他语言也类似有多个版本,根据个人喜好选择使用。


2.JSON
JSON比较小巧灵活,解析容易,唯一不好的就是阅读没有XML那么直观,但XML解析复杂,体积庞大,所以现在web上大多选用JSON作为数据交互处理。

XML注重条理性,而JSON带有面向对象的味道,注重模块化,这也就是JSON不如XML便于阅读的原因,但熟悉对象编程的程序员来说,JSON这是最好的数据交互方案,当然JSON也是给程序员看的,你普通网民需要看JSON吗....

3.简单使用(我喜欢C,所以这里以C为栗子,当然我选的是cJSON这个开源 https://github.com/DaveGamble/cJSON)

下面上一些栗子:

1)创建一个对象模块
cJSON *root = cJSON_CreateObject();
创建好对象,接下来就可以往对象里加东西了
加东西函数
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble")); //添加一个项目(也可以是一个对象块,如下句)
cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject()); //添加一个对象块
cJSON_AddStringToObject(fmt, "type", "rect"); //添加一个string类型的项目
cJSON_AddNumberToObject(fmt, "width", 1920); //添加一个数据类型项目(整型或实型)
cJSON_AddFalseToObject (fmt, "interlace"); //添加一个布尔型false/true

栗子:
   #include <stdio.h>
   #include "cJSON.h"
  
  int main()
  {
       cJSON *root = NULL, *fmt = NULL;
   
      root = cJSON_CreateObject();
      cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
      cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
     cJSON_AddStringToObject(fmt, "type", "rect");
     cJSON_AddNumberToObject(fmt, "width", 1920);
     cJSON_AddNumberToObject(fmt, "height", 1080);
    cJSON_AddNumberToObject(fmt, "iamfloat", 10.80);
     cJSON_AddFalseToObject (fmt, "interlace");
     cJSON_AddNumberToObject(fmt, "frame rate", 24);
     printf("%s\n", cJSON_Print(root)); //cJSON_Print把整个对象当成字符串打印
     cJSON_Delete(root); //释放指针所指空间
 }
输出结果:
{
"name": "Jack (\"Bee\") Nimble",
"format": {
"type": "rect",
"width": 1920,
"height": 1080,
"iamfloat": 10.8,
"interlace": false,
"frame rate": 24
}
}


2)字符串数组array
root = cJSON_CreateStringArray(strings, 7); // strings是一个字符串数组,7是长度
栗子:
 int main()
{
     cJSON *root = NULL;
     const char *strings[7] =
     {
        "Sunday",
        "Monday",
         "Tuesday",
        "Wednesday",
         "Thursday",
        "Friday",
        "Saturday"
     };
 
    root = cJSON_CreateStringArray(strings, 7);
 //上面这句等价于下面这两句:
 //     root = cJSON_CreateArray();
 //     cJSON_AddItemToArray(root, cJSON_CreateStringArray(strings, 7));


     printf("%s\n", cJSON_Print(root));
     cJSON_Delete(root);
      return 0;
  }
输出结果:
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]


多维数组:
栗子:
 int main()
 {
     cJSON *root = NULL;
     int numbers[3][3] =
    {
        {0,-1,0},
        {1,0,0},
        {0,0,1}
    };
    root = cJSON_CreateArray();
     for (int i=0; i<3; i++)
     {
        cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3));
     }
     printf("%s\n", cJSON_Print(root));
     cJSON_Delete(root);
 }
输出结果:
[[0, -1, 0], [1, 0, 0], [0, 0, 1]]


3)raw,这个感觉用到频率不高,它能做的事,用前面介绍的API都可以代替
栗子:
 int main()
 {
     cJSON *root = NULL;
     const char raw[4] =
     {
         "abc\0"
     };
     root = cJSON_CreateRaw(raw);
    printf("%s\n", cJSON_Print(root));
     cJSON_Delete(root);
 }
 输出结果:abc




4. 以上介绍了JSON常见的一些用法,还有其他很多API可用,以葫芦画瓢就可了,下面是一些使用频率比较高的API或宏,这些都来自cJSON.h。
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);


/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);


/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);


/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))

5. 现在有一个xxx.json的配置文件,如何对其读写操作?上栗子

#include <stdarg.h>

#include <stdio.h>

#include "cJSON.h"

int main(int argc, char *argv[])
{

cJSON *pJsonRoot = NULL, *pSub = NULL;
char *p = NULL;
FILE *fp = NULL;
int size;
char buf[256];
pJsonRoot = cJSON_CreateObject();
       if (NULL == pJsonRoot) return 1;

  cJSON_AddFalseToObject (pJsonRoot, "auto-update");
  cJSON_AddStringToObject(pJsonRoot, "device", "V3");
  cJSON_AddStringToObject(pJsonRoot, "target", "BANK");
  p = cJSON_Print(pJsonRoot);
  printf("%s\n", p);
  fp = fopen("/home/Administrator/test/test.json", "w"); //以json数据格式写文件
  if (fp == NULL)
  {
  printf("%s", "fopen failed!");
  return 1;
  }
  if (fwrite(p, strlen(p), 1, fp) <= 0)
  {
  printf("%s", "fwrite failed!");
  fclose(fp);
  return 1;
  }
  fclose(fp);
  free(p);
  cJSON_Delete(pJsonRoot);


  fp = fopen("/home/Administrator/test/test.json", "r"); //从配置文件中读取
  if (fp == NULL)
  {
  printf( "%s", "fopen for read failed!");
  return 1;
  }
  fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  p = (char *)malloc(size+1);
  memset(p, 0, size+1);
  rewind(fp);
  
  if (fread(p, size, 1, fp) <= 0)
  {
  printf( "%s", "fopen for read failed!");
  fclose(fp);
  return 1;
  }
  /*
  while((fgets(buf, 256, fp))!=NULL)
  {
  strcat(p, buf);
  }
  */
  fclose(fp);
  printf("%s\n", p); //这里打出来的内容,json结构应该与上面一样
  pJsonRoot = cJSON_Parse(p);
  if (pJsonRoot == NULL)
  {
  printf( "%s %s", "cJSON_Parse failed!", p);
  goto END;
  }
  pSub = cJSON_GetObjectItem(pJsonRoot, "auto-update");
  if (pSub == NULL)
  {
  printf( "%s", "cJSON_GetObjectItem failed!");
  goto END;
  }
  printf("auto-update=%d\n", pSub->valueint);
  pSub = cJSON_GetObjectItem(pJsonRoot, "device");
  printf("device=%s\n", pSub->valuestring);
  pSub = cJSON_GetObjectItem(pJsonRoot, "target");
  printf("target=%s\n", pSub->valuestring);
  
END:
free(p);
//cJSON_Delete(pSub);  // pSub is child of pJsonRoot, so shall not free, otherwise, aborted error
cJSON_Delete(pJsonRoot);
return 0;

}


6. 修改json配置文件里的一个item

// set item to json configuration file
BOOL set_json(char *itemstr, char *newstr, const char *file_pathname)
{
    FILE                *fp = NULL;
    int                 size = 0;
    char                *pbuf = NULL, *p = NULL;
    cJSON               *pJsonRoot = NULL, *pSub = NULL;
    BOOL                ret = FALSE;
    
    if (file_pathname == NULL)
    {
        return FALSE;
    }
    fp = fopen(file_pathname, "r");
    if (fp == NULL)
    {
        return FALSE;
    }
    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
    pbuf = (char *)malloc(size+1);
    if (pbuf == NULL)
    {
        ret = FALSE;
        goto SET_ERR;
    }
    memset(pbuf, 0, size+1);
    rewind(fp);
    if (fread(pbuf, size, 1, fp) <= 0)
    {
        ret = FALSE;
        goto SET_ERR;
    }
    fclose(fp);
    // get cjson object
    pJsonRoot = cJSON_Parse(pbuf);
    if (pJsonRoot == NULL)
    {
        ret = FALSE;
        goto SET_ERR;
    }
    pSub = cJSON_GetObjectItem(pJsonRoot, itemstr);
    if (pSub)
    {
        cJSON_ReplaceItemInObject(pJsonRoot, itemstr, cJSON_CreateString(newstr)); 
    }
    else
    {
        ret = FALSE;
        goto SET_ERR;
    }
    // save object to file
    p = cJSON_Print(pJsonRoot);
    fp = fopen(file_pathname, "w");
    if (fp == NULL)
    {
        //printf("%s", "fopen failed!");
        ret = FALSE;
        goto SET_ERR;
    }
    if (fwrite(p, strlen(p), 1, fp) <= 0)
    {
        //printf("%s", "fwrite failed!");
        ret = FALSE;
        goto SET_ERR;
    }


    ret = TRUE;


SET_ERR: 
    if (fp) fclose(fp);
    if (p) free(p);
    if (pbuf) free(pbuf);
    if (pJsonRoot) cJSON_Delete(pJsonRoot);
    return ret;
}


使用总结:cJSON主要有两个用法一是对象object,另一个是数组array.

可以直接在linux,或 windows C/C++编译器下直接编译使用的cJSON.c和.h在我的资源下载里有。

http://download.csdn.net/detail/js_gary/9865487

原创粉丝点击