使用cJSON創建JSON字符串
在Linux下,使用C語言編程,開始JSON字符串的創建。我們還是一步步來,逐漸由簡單到複製。
1,下載源碼
可以從如下網站來下載:https://sourceforge.net/projects/cjson/ 。
2,包含cJSON的源碼
下載下來,解壓後,從裏面找到兩個文件(cJSON.c、cJSON.h),複製到我們的工程裏面。只需在函數中包含頭文件(#include “cJSON.h”),然後和cJSON.c一起編譯即可使用。
3,創建一個鍵值對
首先是一個簡單的鍵值對字符串,要生成的目標如下:
{"firstName":"Brett"}
要進行創建,就是先確定鍵與值,然後轉爲cJSON格式。我們很容易就能明確鍵爲firstName,值爲Brett,可是,使用cJSON怎麼創建呢?
對於這個簡單的例子,我們需要調用cJSON的五個接口函數就可以實現創建了。(有人不樂意了:都五個函數了,你還說“就可以了”----其實是一法通,百法通,學會了這個創建,其他的創建動作都是非常類似的。)
這五個函數的原型如下:
cJSON*cJSON_CreateObject ();
cJSON*cJSON_CreateString(const char *string);
voidcJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
voidcJSON_Delete(cJSON *c);
char*cJSON_Print(cJSON *item);
下面按創建過程來描述一次:
(1) 首先調用cJSON_ CreateObject ()函數,創建一個JSON對象,之後便可向這個對象中添加string或int等內容的數據項了。使用該函數會通過malloc()函數在內存中開闢一個空間,使用完成需要手動釋放。
cJSON*root=cJSON_CreateObject();
(2) 調用cJSON_CreateString ()函數,由一個字符串生成一個cJSON的數據項。
cJSON*item=cJSON_CreateString("Brett");
(3) 將上一步生成的數據項與其鍵值("firstName")一起添加到root對象中。
cJSON_AddItemToObject(root,"firstName",item);
其實到這一步,我們在內存中的cJSON對象就已經構建完成了,後面是展示結果了。
(4) 將cJSON對象的內容解析爲字符串,並展示出來。
out=cJSON_Print(root);
printf("out:%s\n",out);
(5) 通過cJSON_Delete(),釋放cJSON_CreateObject ()分配出來的內存空間。
cJSON_Delete(root);
(6) 釋放cJSON_Print ()分配出來的內存空間。
free(out);
這樣就完成了一次cJSON接口調用,實現了字符串的創建工作。
4,轉換一個結構體
接下來,我們來個複雜一點的,將一個結構體轉換爲JSON字符串,結構體定義如下:
typedefstruct
{
char firstName[32];
char lastName[32];
char email[64];
int age;
float height;
} PERSON;
看起來比一個鍵值對複雜多了,我們又需要學習新的接口函數了嗎?
是的,由於出現了數字,我們需要學習一個新函數:
cJSON *cJSON_CreateNumber(double num);
當然,創建的步驟要更復雜一些,下面我仍然是按創建過程來描述一次:
(1)還是先調用cJSON_ CreateObject ()函數,創建一個JSON對象root,做爲根(咱們可以把JSON串看成是一顆樹)。使用該函數會通過malloc()函數在內存中開闢一個空間,使用完成需要手動釋放。
cJSON*root=cJSON_CreateObject();
(2)繼續調用cJSON_ CreateObject ()函數,創建一個JSON對象obj_person,做爲掛載結構體內容的對象。掛載內容之後,這個對象是要掛載到根上的。
cJSON*obj_person=cJSON_CreateObject();
(3)根據數據生成cJSON格式的數據項,調用cJSON_AddItemToObject()函數掛載到obj_person對象上。這個過程,要多次重複,直到將所有數據都添加上。此時要注意,不同的成員,生成的方法是不一樣的。
cJSON*item=cJSON_CreateString(person->firstName);
cJSON_AddItemToObject(obj_person,"firstName",item);
item=cJSON_CreateString(person->lastName);
cJSON_AddItemToObject(obj_person,"lastName",item);
item=cJSON_CreateString(person->email);
cJSON_AddItemToObject(obj_person,"email",item);
item=cJSON_CreateNumber(person->age);
cJSON_AddItemToObject(obj_person,"age",item);
item=cJSON_CreateNumber(person->height);
cJSON_AddItemToObject(obj_person,"height",item);
(4)將obj_person對象掛載到根上。
cJSON_AddItemToObject(root,"person",obj_person);
到這一步,我們在內存中的cJSON對象就已經構建完成了,後面就是展示結果。
(5)將cJSON對象的內容解析爲字符串,並展示出來。
out=cJSON_Print(root);
printf("out:%s\n",out);
(6)通過cJSON_Delete(),釋放cJSON_CreateObject ()分配出來的內存空間。這裏說明一下,我們前面調用了2次cJSON_CreateObject (),最後只需要針對root調用一次釋放即可,因爲第二次創建的對象也是掛接在root上的。
cJSON_Delete(root);
(7)釋放cJSON_Print ()分配出來的內存空間。
free(out);
至此,我們就使用cJSON接口完成了由結構體生成JSON字符串的工作。
5,創建結構體數組的JSON串
最後,我們來個更復雜一些的,來轉換一個數組,並且數組的成員是結構體!我們要生成的目標如下:
{
"people":[
{"firstName":"z","lastName":"Jason","email":"[email protected]","height":1.67},
{"lastName":"jadena","email":"[email protected]","age":8,"height":1.17},
{"email":"[email protected]","firstName":"z","lastName":"Juliet","age":36,"height":1.55}
]
}
此時,我們又需要學習新的接口了,一個是創建數組,一個是取數組成員,函數原型如下:
cJSON*cJSON_CreateArray(void);
void cJSON_AddItemToArray(cJSON *array, cJSON*item);
由於前面已經實現了單個結構體的轉換,這裏我們重點關注下數組的相關調用。
(1)還是先調用cJSON_ CreateObject ()函數,創建一個JSON對象root,做爲根。
(2)調用cJSON_CreateArray ()函數,創建一個JSON數組對象,準備掛載多個結構體對象。掛載內容之後,這個數組對象是要掛載到根上的。
cJSON*array_person=cJSON_CreateArray();
(3)生成一個結構體對象,並相應添加數據,然後調用cJSON_AddItemToArray()函數掛載到數組對象上。這個過程,要多次重複,直到將所有結構體對象都添加上。
cJSON_AddItemToArray(array_person,obj_person);
(4)將數組對象掛載到根上。
cJSON_AddItemToObject(root,"people",array_person);
到這一步,我們在內存中的cJSON對象就已經構建完成了。
(5)將cJSON對象的內容解析爲字符串,並展示出來。
(6)通過cJSON_Delete(),釋放cJSON_CreateObject ()分配出來的內存空間。
(7)釋放cJSON_Print ()分配出來的內存空間。
這樣,我們就使用cJSON接口完成了將結構體數組轉換成JSON字符串的工作。
詳細代碼見後文附帶例程。
說明:
本文所附帶例程,實現了結構體數組生成JSON字符串,只是一個學習之作,對於初學cJSON的同學,可以有些借鑑參考的作用。
附帶例程:
[cpp] view plain copy
- #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_str4.txt");
- return 0;
- }
- //create a key-value pair
- int str_to_cJSON(char *json_string, char *str_val)
- {
- char * out=NULL;
- cJSON *root=cJSON_CreateObject();
- if (!root)
- {
- printf("Error before: [%s]\n",cJSON_GetErrorPtr());
- return -1;
- }
- else
- {
- cJSON *item=cJSON_CreateString("Brett");
- cJSON_AddItemToObject(root,"firstName",item);
- out=cJSON_Print(root);
- printf("out2:%s\n",out);
- cJSON_Delete(root);
- if(out!=NULL)
- {
- free(out);
- }
- }
- return 0;
- }
- //create a object from struct
- int struct_to_cJSON(char *json_string, people *person)
- {
- if((json_string==NULL) || (person==NULL))
- {
- printf("%s: input is invalid",__func__);
- }
- char * out=NULL;
- cJSON *root=cJSON_CreateObject();
- if (!root)
- {
- printf("Error before: [%s]\n",cJSON_GetErrorPtr());
- return -1;
- }
- else
- {
- cJSON *obj_person=cJSON_CreateObject();
- cJSON *item=cJSON_CreateString(person->firstName);
- cJSON_AddItemToObject(obj_person,"firstName",item);
- item=cJSON_CreateString(person->lastName);
- cJSON_AddItemToObject(obj_person,"lastName",item);
- item=cJSON_CreateString(person->email);
- cJSON_AddItemToObject(obj_person,"email",item);
- item=cJSON_CreateNumber(person->age);
- cJSON_AddItemToObject(obj_person,"age",item);
- item=cJSON_CreateNumber(person->height);
- cJSON_AddItemToObject(obj_person,"height",item);
- cJSON_AddItemToObject(root,"person",obj_person);
- out=cJSON_Print(root);
- printf("out2:%s\n",out);
- cJSON_Delete(root);
- if(out!=NULL)
- {
- memcpy(json_string,out,strlen(out));
- free(out);
- }
- }
- return 0;
- }
- //a struct array to CJSON
- int struct_array_to_cJSON(char *text, people worker[])
- {
- cJSON *json,*arrayItem,*item,*object;
- int i;
- 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);
- }
- if((text==NULL) || (worker==NULL))
- {
- printf("%s: input is invalid",__func__);
- }
- char * out=NULL;
- cJSON *root=cJSON_CreateObject();
- if (!root)
- {
- printf("Error before: [%s]\n",cJSON_GetErrorPtr());
- return -1;
- }
- else
- {
- cJSON *array_person=cJSON_CreateArray();
- for(i=0;i<3;i++)
- {
- cJSON *obj_person=cJSON_CreateObject();
- cJSON *item=cJSON_CreateString(worker[i].firstName);
- cJSON_AddItemToObject(obj_person,"firstName",item);
- item=cJSON_CreateString(worker[i].lastName);
- cJSON_AddItemToObject(obj_person,"lastName",item);
- item=cJSON_CreateString(worker[i].email);
- cJSON_AddItemToObject(obj_person,"email",item);
- item=cJSON_CreateNumber(worker[i].age);
- cJSON_AddItemToObject(obj_person,"age",item);
- item=cJSON_CreateNumber(worker[i].height);
- cJSON_AddItemToObject(obj_person,"height",item);
- cJSON_AddItemToArray(array_person,obj_person);
- }
- cJSON_AddItemToObject(root,"people",array_person);
- out=cJSON_Print(root);
- printf("out:%s\n",out);
- cJSON_Delete(root);
- if(out!=NULL)
- {
- memcpy(text,out,strlen(out));
- free(out);
- }
- }
- return 0;
- }
- // create CJSON, write file
- void dofile(char *filename)
- {
- FILE *f;
- int len;
- char data[1024];
- f=fopen(filename,"wb");
- fseek(f,0,SEEK_END);
- len=ftell(f);
- fseek(f,0,SEEK_SET);
- printf("read file %s complete, len=%d.\n",filename,len);
- // char str_name[40];
- // int ret = str_to_cJSON(data, str_name);
- people worker[3]={
- {0,"zhong","Jason","[email protected]",0,1.67},
- {1,"","jadena","[email protected]",8,1.17},
- {2,"zhu","Juliet","[email protected]",36,1.55}
- };
- // struct_to_cJSON(data, &worker[1]);
- struct_array_to_cJSON(data, worker);
- fwrite(data,1,strlen(data),f);
- fclose(f);
- }
http://blog.csdn.net/lintax/article/details/51549345