TA的每日心情 | 慵懒 昨天 10:54 |
---|
签到天数: 186 天 连续签到: 2 天 [LV.7]常住居民III
|
本帖最后由 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[0]);
- 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[i]));
- cJSON_AddItemToObject(root, "score", score);
- */
- // print Json string
- jstr = cJSON_Print(root);
- printf("%s\n", jstr);
- FILE* fp=fopen(argv[1],"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[size] = '\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[0]);
- return 1;
- }
- cJSON *json = parse_json_file(argv[1]);
- 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的话,还会更加方便,但是运行速度感人。
|
|