stm1024 发表于 2024-11-29 22:48:42

【米尔-MYD-LR3568-GK开发板--试用评测】17——处理Json

本帖最后由 stm1024 于 2024-11-29 22:53 编辑

JSON(JavaScript Object Notation,JavaScript对象表示法)是基于ECMAScript的一个子集设计的,是一种开放标准的文件格式和数据交换格式,它易于人阅读和编写,同时也易于机器解析和生成。JSON独立于语言设计,很多编程语言都支持JSON格式的数据交换。JSON是一种常用的数据格式,在电子数据交换中有多种用途,包括与服务器之间的Web应用程序的数据交换。其简洁和清晰的层次结构有效地提升了网络传输效率,使其成为理想的数据交换语言。其文件通常使用扩展名.json。
本次测试使用C语言处理Json文件。
1. 使用到的库
推荐使用cJson库,‌cJson‌是一个轻量级的JSON解析库,主要用于C语言环境中处理JSON数据。它提供了一系列函数来创建、解析、修改和序列化JSON对象。cJson的基本功能
‌创建JSON对象‌:可以使用cJSON_CreateObject、cJSON_CreateArray等函数创建JSON对象和数组。
‌添加元素‌:可以通过cJSON_AddItemToObject、cJSON_AddItemToArray等函数向JSON对象或数组中添加元素。
‌解析JSON字符串‌:使用cJSON_Parse函数可以将JSON格式的字符串解析为cJson结构体表示的对象。
‌生成JSON字符串‌:通过cJSON_Print函数可以将cJson结构体表示的对象转换为JSON格式的字符串。
cJson的使用场景
‌数据交换‌:在C语言编写的应用程序之间进行数据交换时,cJson可以方便地将数据序列化为JSON格式,便于传输和存储。
‌配置文件‌:用于读取和写入配置文件,将复杂的配置信息以JSON格式存储和读取。
‌网络通信‌:在网络通信中,cJson可以将结构化数据转换为JSON格式,便于通过HTTP等协议传输。
cJson的优缺点
‌优点‌:
‌轻量级‌:cJson的实现较为简单,占用内存少,适合嵌入式系统和资源有限的设备。
‌易用性‌:提供了丰富的API,易于使用和理解。
‌跨平台‌:由于是C语言编写,可以在多种平台上使用。
‌缺点‌:
‌性能‌:相对于一些高性能的JSON处理库,cJson在处理大量数据时可能效率较低。
‌功能限制‌:虽然提供了基本的JSON处理功能,但对于一些特殊需求可能需要其他库的支持。

2. 写Json文件
如果我们需要将数据以Json方式传递,则可以通过写文件的方式生成Json文件,实现代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

int main(int argc, const char *argv[])
{
    if (argc < 2)
    {
      printf("Usage: %s filename\n", argv);
      return 1;
    }
    cJSON *root = cJSON_CreateObject();
    double ds[] = {65.6, 33.4, 95.6, 87.8};
    char *jstr = NULL;
    int i;
    cJSON_AddStringToObject(root, "name", "Bob");

    // add an array of strings
    cJSON *hobby = cJSON_CreateArray();
    cJSON_AddItemToArray(hobby, cJSON_CreateString("basketball"));
    cJSON_AddItemToArray(hobby, cJSON_CreateString("football"));
    cJSON_AddItemToArray(hobby, cJSON_CreateString("swim"));
    cJSON_AddItemToObject(root, "hobby", hobby);
    // add an array of doubles
   
    //method 1:
    cJSON* score = cJSON_CreateDoubleArray(ds,sizeof(ds)/sizeof(double));
    cJSON_AddItemToObject(root, "score", score);
   
    /*
    // method 2:
    cJSON *score = cJSON_CreateArray();
    for (i = 0; i < sizeof(ds) / sizeof(double); i++)
      cJSON_AddItemToArray(score, cJSON_CreateNumber(ds));
    cJSON_AddItemToObject(root, "score", score);
    */

    // print Json string
    jstr = cJSON_Print(root);
    printf("%s\n", jstr);
    FILE* fp=fopen(argv,"w");
    fwrite(jstr,sizeof(char),strlen(jstr),fp);
    fclose(fp);
    free(jstr); // remember to free it
    cJSON_Delete(root);
    return 0;
}在开发板上使用gcc编译:
gcc -g cJSON.c cjw.c -lm -o cjw运行效果如下:

可以看到在同名文件夹下生成了一个名为hello.json的文件:

3. 读Json文件
读取Json文件或者Json字符串是一样的效果,实现起来也很简单,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

//read json file and parse it into a cJSON object
cJSON *parse_json_file(const char *filename)
{
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL) {
      printf("Failed to open file %s\n", filename);
      return NULL;
    }
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *json_str = (char *)malloc(size + 1);
    fread(json_str, 1, size, fp);
    json_str = '\0';
    fclose(fp);
    cJSON *json = cJSON_Parse(json_str);
    free(json_str);
    return json;
}

//print cJSON object in a formatted way
void print_json(cJSON *json)
{
    char *str = cJSON_Print(json);
    printf("%s\n", str);
    free(str);
}

//example usage of the above functions
int main(int argc, char **argv)
{
    if (argc < 2)
    {
      printf("Usage: %s filename\n", argv);
      return 1;
    }
    cJSON *json = parse_json_file(argv);
    if (json == NULL)
      return 1;
   
    print_json(json);
   
    //get the value of a key in the json object
    cJSON *name = cJSON_GetObjectItem(json, "name");
    if (name != NULL && name->type == cJSON_String)
      printf("Name: %s\n", name->valuestring);
   
    //get the value of an array element
    cJSON *array = cJSON_GetObjectItem(json, "score");
    if (array != NULL && array->type == cJSON_Array)
    {
      int i;
      for (i = 0; i < cJSON_GetArraySize(array); i++)
      {
            cJSON *element = cJSON_GetArrayItem(array, i);
            if (element != NULL && element->type == cJSON_Number)
                printf("Element %d: %f\n", i, element->valuedouble);
      }
    }

    cJSON_Delete(json);
    return 0;
}
同样使用开发板上的gcc编译一下,运行效果如下:
代码中第一部分是直接解析了字符串并打印,第二部分是读取了名称和score部分的值,可见解析正确。
对于嵌套的Json对象,当然也可以实现递归的解析函数,这里就不展开介绍了。此外,如果使用python的话,还会更加方便,但是运行速度感人。


页: [1]
查看完整版本: 【米尔-MYD-LR3568-GK开发板--试用评测】17——处理Json