Uso básico de la biblioteca Json para dispositivos integrados.

Hola a todos, hoy presentaré una biblioteca Json liviana basada en lenguaje C: cJson. Se puede utilizar en dispositivos integrados con recursos limitados.

 

cJSON es un analizador JSON estándar ANSI-C simple, ultraligero, portátil, de un solo archivo.

cJSON es un proyecto de código abierto, dirección de descarga de github:

https://github.com/DaveGamble/cJSON

cJSON, actualmente existen dos archivos principales, uno  cJSON.c para cada  cJSON.h. Al usarlo, simplemente incluya el archivo de encabezado.

Si se usa en el sistema operativo Linux, es necesario agregar la biblioteca matemática al compilar  libm.so, de la siguiente manera:

gcc  *.c  cJSON.c  -lm

1. estructura cJSON

Se define una estructura muy importante en  cJSON cJSON.h . Si desea familiarizarse con el uso de las funciones de la biblioteca cJSON, puede comenzar con la estructura cJSON. La estructura cJSON es la siguiente:

typedef struct cJSON {  
     struct cJSON *next,*prev;   
     struct cJSON *child;   
     int type;   
     char *valuestring;        // value值是字符串类型
     int valueint;  
     double valuedouble;   
     char *string;             // 对象中的key
} cJSON; 

Aquí hay algunas explicaciones sobre esta estructura:

  1. La estructura cJOSN es una lista doblemente enlazada y se puede acceder a la siguiente capa a través del puntero secundario.

  2. La variable de tipo del miembro de la estructura se utiliza para describir el tipo del elemento de datos (si es un par clave-valor que representa el tipo del valor del valor), el elemento de datos puede ser una cadena, un número entero o un flotante. tipo de punto.

  • Si es un valor entero, el valor se puede sacar mediante valueint

  • Si es un tipo de punto flotante, el valor se puede sacar mediante valuedouble

  • Si es un tipo de cadena, el valor se puede obtener a través de valuestring

  1. La cadena de miembro de la estructura representa el nombre de la clave en el par clave-valor.

Como biblioteca de análisis de formato Json, la función principal de cJSON es construir y analizar el formato Json, por ejemplo, para enviar datos: el propósito es encapsular los datos que enviará el remitente en forma de json y luego enviarlos. Después de recibir los datos, el receptor aún presiona el análisis del formato JSON y obtiene los datos deseados.

2. API cJson

Los datos en formato Json no son más que dos tipos de objetos Json y matrices Json. La cadena de datos Json creada puede ser uno de los dos, o una combinación de los dos, sin importar cuál esté disponible llamando a la función API correspondiente. fácilmente.

2.1 Encapsulación de datos

Puede ver algunas declaraciones de funciones en  cJSON.h el archivo de encabezado. Al llamar a estas funciones de creación, los tipos de datos admitidos por Json se pueden encapsular en tipos de estructura cJSON:

// 空值类型
extern cJSON *cJSON_CreateNull(void);
// 布尔类型
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
// 数值类型
extern cJSON *cJSON_CreateNumber(double num);
// 字符串类型
extern cJSON *cJSON_CreateString(const char *string);
// json数组(创建空数组)
extern cJSON *cJSON_CreateArray(void);
// json对象(创建空对象)
extern cJSON *cJSON_CreateObject(void);

Además, la biblioteca cJson también nos proporciona algunas funciones de operación más convenientes, que también se pueden inicializar al crear una matriz.

// 创建一个Json数组, 元素为整形
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// 创建一个Json数组, 元素为浮点
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// 创建一个Json数组, 元素为字符串类型
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);

2.2 Operación de objetos Json

Después de obtener un objeto Json, puede agregar pares clave-valor al objeto, puede usar cJSON_AddItemToObject()

extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

La afiliación de nodos en la biblioteca cJSON se mantiene a través de un árbol, y cada capa de nodos se mantiene a través de una lista vinculada, de modo que se pueda analizar el significado de los parámetros de la función:

  • objeto: el par clave-valor que se agregará pertenece a ese nodo

  • cadena: el valor clave del par clave-valor agregado

  • elemento: el valor del par clave-valor agregado (primero debe encapsularse en una estructura de tipo cJSON)

Para que mi operación sea más conveniente, la biblioteca cJson también nos proporciona algunas funciones macro, para que podamos agregar rápidamente pares clave-valor a los objetos Json.

#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))

También podemos extraer el valor correspondiente según el valor clave en el objeto Json. El prototipo de la función API es el siguiente:

extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

2.3 Operación de matriz Json

Agregue datos a la matriz Json (los datos originales deben convertirse primero al tipo de estructura cJSON)

extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);

Obtenga la cantidad de elementos en la matriz Json:

extern int cJSON_GetArraySize(cJSON *array);

Obtenga el elemento en la posición especificada en la matriz Json. Si devuelve NULL, significa que la adquisición del valor falló.

extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);

2.4 Serialización

La serialización es el proceso de convertir datos en formato Json en cadenas, la biblioteca cJson nos proporciona 3 funciones de conversión, de la siguiente manera:

El primer elemento de parámetro representa el nodo raíz del bloque de datos Json.

extern char  *cJSON_Print(cJSON *item);
extern char  *cJSON_PrintUnformatted(cJSON *item);
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
  • Al llamar  cJSON_Print() a la función podemos obtener una cadena Json formateada (con nuevas líneas, parece más intuitivo)

  • Al llamar  cJSON_PrintUnformatted() a la función se obtendrá una cadena Json sin formato (sin saltos de línea, todos los datos en la misma línea).

  • La  cJSON_PrintBuffered() función de llamada utiliza la estrategia de búfer para convertir la entidad Json en una cadena. El parámetro prebuffer es el tamaño del búfer especificado y el parámetro  fmt==0 significa sin formato y fmt==1 formateado.

Durante el proceso de codificación, podemos llamar a las funciones de operación relevantes de acuerdo con nuestras necesidades reales para obtener la cadena Json en el formato correspondiente.

2.5 Análisis de cadenas Json

Si obtenemos una cadena en formato Json y queremos leer los datos que contiene, debemos analizar la cadena. El método de procesamiento es convertir la cadena en una estructura cJSON y luego leer los datos originales que contiene en función de esta estructura. , el prototipo de función de la función de conversión es el siguiente:

extern cJSON *cJSON_Parse(const char *value);

2.6 Liberación de memoria

Cuando encapsulamos los datos en un nodo de tipo de estructura cJSON, obtendremos una parte de la memoria del montón. Cuando liberamos un nodo, podemos llamar a la función de eliminación proporcionada por la biblioteca cJson. El prototipo de la función es el siguiente  cJSON_Delete():

extern void   cJSON_Delete(cJSON *c);

El parámetro de esta función es la dirección del nodo a liberar, aquí enfatizamos un punto: cuando se libera la dirección de memoria, se eliminarán el nodo actual y sus nodos secundarios.

3. Encapsulación de datos Json

3.1 Ejemplo de operación de objeto Json

Cree un objeto y agregue cadenas y claves enteras a este objeto:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"cJSON.h"
 
int main()
{
    cJSON * root;
    cJSON *arry;

    root=cJSON_CreateObject();                     // 创建根数据对象
    cJSON_AddStringToObject(root,"name","luffy");  // 添加键值对
    cJSON_AddStringToObject(root,"sex","man");     // 添加键值对
    cJSON_AddNumberToObject(root,"age",19);        // 添加键值对

    char *out = cJSON_Print(root);   // 将json形式转换成字符串
    printf("%s\n",out);

    // 释放内存  
    cJSON_Delete(root);  
    free(out);        
}

resultado de la operación

{
 "name": "luffy",
 "sex": "man",
 "age": 19
}

Algunas aclaraciones:

  • cJSON_CreateObject La función puede crear un objeto raíz y devolver un puntero cJSON. Una vez que se agota el puntero, es necesario llamarlo manualmente  cJSON_Delete(root) para recuperar la memoria.

  • La función malloc está encapsulada dentro de la función  cJSON_Print() , por lo que es necesario utilizar la función free() para liberar el espacio de memoria ocupado por out.

3.2 Ejemplo de operación de matriz Json

Cree una matriz y agregue una cadena y un número a la matriz

int main(int argc, char **argv)
{
    cJSON *root;
    root = cJSON_CreateArray();
    cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));
    cJSON_AddItemToArray(root, cJSON_CreateNumber(10)); 
    // char *s = cJSON_Print(root);
    char *s = cJSON_PrintUnformatted(root);
    if(s)
    {
        printf(" %s \n",s);
        free(s);
    }
    cJSON_Delete(root);
    return 0;
}

resultado de la operación:

["Hello world",10]

3.3 Uso anidado de matrices y objetos Json

El objeto contiene una matriz, la matriz contiene objetos y se agregan una cadena y un número al objeto.

{
    "person":[{
        "name":"luffy",
        "age":19
    }]
}

Código de muestra:

int main(int argc, char **argv)
{
    cJSON *root, *body, *list;
    // josn 对象 root
    root = cJSON_CreateObject();
    // root 添加键值对 person:json数组A
    cJSON_AddItemToObject(root,"person", body = cJSON_CreateArray());
    // json数组A 添加Json对象B
    cJSON_AddItemToArray(body, list = cJSON_CreateObject());
    // 在json对象B中添加键值对: "name":"luffy"
    cJSON_AddStringToObject(list,"name","luffy");
    // 在json对象B中添加键值对: "age":19
    cJSON_AddNumberToObject(list,"age",19);
 
    // char *s = cJSON_Print(root);
    char *s = cJSON_PrintUnformatted(root);
    if(s)
    {
        printf(" %s \n",s);
        free(s);
    }
    if(root)
    {
        cJSON_Delete(root); 
    }
    return 0;
}

resultado de la operación:

{"person":[{"name":"luffy","age":19}]}

4. Analizar la cadena Json

4.1 Análisis de objetos Json

El proceso de análisis de la cadena Json es opuesto al proceso de encapsulación de datos. Supongamos que tenemos una cadena Json de este tipo (las comillas dobles en la cadena deben traducirse a caracteres comunes mediante caracteres de escape):

{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}

El código de muestra es el siguiente:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
 
int main()
{
    cJSON *json, *name, *sex, *age;
    char* out="{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}";
 
    json = cJSON_Parse(out); //解析成json形式
    name = cJSON_GetObjectItem(json, "name");  //获取键值内容
    sex = cJSON_GetObjectItem(json, "sex");
    age = cJSON_GetObjectItem(json, "age");
 
    printf("name:%s,sex:%s,age:%d\n", name->valuestring, sex->valuestring, age->valueint);
 
    cJSON_Delete(json);  //释放内存 
}

Resultado de salida:

name:luffy,sex:man,age:19

Si es en un lugar estricto, primero se debe determinar el tipo de cada artículo y luego se debe considerar el valor .

4.2 Análisis de objetos Json anidados

Para hacerlo un poco más difícil, analicemos un objeto Json anidado, los datos son los siguientes:

{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}
int main()
{
    char *s = "{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}";
    cJSON *root = cJSON_Parse(s);
    if(!root) 
    {
        printf("get root faild !\n");
        return -1;
    }

    cJSON *js_list = cJSON_GetObjectItem(root, "list");
    if(!js_list) 
    {
        printf("no list!\n");
        return -1;
    }
    printf("list type is %d\n",js_list->type);

    cJSON *name = cJSON_GetObjectItem(js_list, "name");
    if(!name) 
    {
        printf("No name !\n");
        return -1;
    }
    printf("name type is %d\n",name->type);
    printf("name is %s\n",name->valuestring);

    cJSON *age = cJSON_GetObjectItem(js_list, "age");
    if(!age) 
    {
        printf("no age!\n");
        return -1;
    }
    printf("age type is %d\n", age->type);
    printf("age is %d\n",age->valueint);

    cJSON *js_other = cJSON_GetObjectItem(root, "other");
    if(!js_other) 
    {
        printf("no list!\n");
        return -1;
    }
    printf("list type is %d\n",js_other->type);

    cJSON *js_name = cJSON_GetObjectItem(js_other, "name");
    if(!js_name) 
    {
        printf("No name !\n");
        return -1;
    }
    printf("name type is %d\n",js_name->type);
    printf("name is %s\n",js_name->valuestring);

    if(root)
    {
        cJSON_Delete(root);
    }
    return 0;
}

resultado de impresión:

list type is 6
name type is 4
name is luffy
age type is 3
age is 19
list type is 6
name type is 4
name is ace

4.3 Análisis de la matriz Json

Si la cadena Json que encontramos está en formato de matriz Json, el método de procesamiento es similar al de un objeto Json. Por ejemplo, queremos analizar la siguiente cadena:

{\"names\":[\"luffy\",\"robin\"]}
int main(int argc, char **argv)
{
    char *s = "{\"names\":[\"luffy\",\"robin\"]}";
    cJSON *root = cJSON_Parse(s);
    if(!root) 
    {
        printf("get root faild !\n");
        return -1;
    }
    cJSON *js_list = cJSON_GetObjectItem(root, "names");
    if(!js_list)
    {
        printf("no list!\n");
        return -1;
    }
    int array_size = cJSON_GetArraySize(js_list);
    printf("array size is %d\n",array_size);
    for(int i=0; i< array_size; i++) 
    {
        cJSON *item = cJSON_GetArrayItem(js_list, i);
        printf("item type is %d\n",item->type);
        printf("%s\n",item->valuestring);
    }

    if(root)
    {
        cJSON_Delete(root);
    }
    return 0;
}

4.4 Análisis de matrices y objetos Json anidados

El número más complejo de cadenas Json es la forma anidada de objetos Json y matrices Json. A continuación se muestra un ejemplo para demostrar cómo analizarlos. El formato de cadena es el siguiente:

{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}

Al analizar, solo necesitamos analizar capa por capa según la relación de afiliación:

  • El nodo raíz es un objeto Json. Según el valor clave en el nodo raíz, se extrae el valor correspondiente y se obtiene una matriz Json.

  • Lea el tamaño de la matriz Json y recorra cada elemento en su interior, cada elemento es un objeto Json

  • Extraiga el valor correspondiente del par clave-valor en el objeto Json de acuerdo con el valor clave

  • El código de muestra para leer el valor correspondiente al tipo real del valor recuperado es el siguiente:

#include "cJSON.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    char *s = "{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}";
    cJSON *root = cJSON_Parse(s);
    if(!root) 
    {
        printf("get root faild !\n");
        return -1;
    }
    cJSON *list = cJSON_GetObjectItem(root, "list");
    if(!list)
    {
        printf("no list!\n");
        return -1;
    }
    int array_size = cJSON_GetArraySize(list);
    printf("array size is %d\n",array_size);
    
    for(int i=0; i< array_size; i++) 
    {
        cJSON* item = cJSON_GetArrayItem(list, i);
        cJSON* name = cJSON_GetObjectItem(item, "name");
        printf("name is %s\n",name->valuestring);
        cJSON* age = cJSON_GetObjectItem(item, "age");
        printf("age is %d\n",age->valueint);
    }

    if(root)
    {
        cJSON_Delete(root);
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_41114301/article/details/132397101
Recomendado
Clasificación