主页 > 互联网  > 

JSON格式,C语言自己实现,以及直接调用库函数(一)

JSON格式,C语言自己实现,以及直接调用库函数(一)

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。

1. 简单对象 JSON 对象是由键值对组成,用花括号 {} 包裹,键和值之间用冒号 : 分隔,多个键值对之间用逗号 , 分隔。

{ "name": "John Doe", "age": 30, "isStudent": false, "hometown": null }

2. 嵌套对象 JSON 对象可以嵌套,即一个对象的键对应的值可以是另一个对象。

json { "person": { "name": "Alice", "age": 25, "contact": { "email": "alice@example ", "phone": "123-456-7890" } } }

3. 数组 JSON 数组是由值组成的有序列表,用方括号 [] 包裹,值之间用逗号 , 分隔。数组中的值可以是不同的数据类型,也可以是对象或数组。

[ "apple", "banana", "cherry" ]

4. 对象数组 数组中的元素可以是 JSON 对象。

[ { "id": 1, "name": "Product A", "price": 19.99 }, { "id": 2, "name": "Product B", "price": 29.99 } ]

5. 复杂嵌套结构 结合对象和数组可以形成更复杂的嵌套结构。

{ "employees": [ { "name": "Bob", "department": "Sales", "projects": [ { "projectName": "Project X", "startDate": "2023-01-01" }, { "projectName": "Project Y", "startDate": "2023-06-01" } ] }, { "name": "Eve", "department": "Marketing", "projects": [ { "projectName": "Project Z", "startDate": "2023-03-01" } ] } ] }

6. 包含不同数据类型的对象

{ "title": "Sample Document", "author": { "firstName": "Jane", "lastName": "Smith" }, "tags": ["document", "sample"], "views": 1234, "isPublished": true }

二、

如果没有现成的 JSON 库,要自己实现 JSON 数据的解析和生成,可以按照 JSON 数据的结构特点,通过字符串处理来完成。以下分别介绍如何手动实现 JSON 对象和数组的解析与生成。

1. JSON 解析 解析思路 JSON 对象:JSON 对象由键值对组成,键和值之间用冒号 : 分隔,键值对之间用逗号 , 分隔,整体用花括号 {} 包裹。解析时需要识别键和值,处理嵌套对象和数组。 JSON 数组:JSON 数组由值组成,值之间用逗号 , 分隔,整体用方括号 [] 包裹。解析时需要逐个提取数组元素。

#include <stdio.h> #include <stdlib.h> #include <string.h> // 跳过空白字符 void skip_whitespace(const char **json) { while (**json == ' ' || **json == '\t' || **json == '\n' || **json == '\r') { (*json)++; } } // 解析字符串 char *parse_string(const char **json) { (*json)++; // 跳过起始的双引号 const char *start = *json; while (**json != '\0' && **json != '"') { (*json)++; } size_t len = *json - start; char *str = (char *)malloc(len + 1); if (str == NULL) { return NULL; } memcpy(str, start, len); str[len] = '\0'; (*json)++; // 跳过结束的双引号 return str; } // 解析数字 int parse_number(const char **json) { int num = 0; while (**json >= '0' && **json <= '9') { num = num * 10 + (**json - '0'); (*json)++; } return num; } // 解析 JSON 对象 void parse_object(const char **json) { (*json)++; // 跳过起始的花括号 skip_whitespace(json); while (**json != '}') { char *key = parse_string(json); skip_whitespace(json); (*json)++; // 跳过冒号 skip_whitespace(json); if (**json == '"') { char *value = parse_string(json); printf("Key: %s, Value: %s\n", key, value); free(value); } else if (**json >= '0' && **json <= '9') { int value = parse_number(json); printf("Key: %s, Value: %d\n", key, value); } free(key); skip_whitespace(json); if (**json == ',') { (*json)++; skip_whitespace(json); } } (*json)++; // 跳过结束的花括号 } // 解析 JSON 数组 void parse_array(const char **json) { (*json)++; // 跳过起始的方括号 skip_whitespace(json); while (**json != ']') { if (**json == '"') { char *value = parse_string(json); printf("Array value: %s\n", value); free(value); } else if (**json >= '0' && **json <= '9') { int value = parse_number(json); printf("Array value: %d\n", value); } skip_whitespace(json); if (**json == ',') { (*json)++; skip_whitespace(json); } } (*json)++; // 跳过结束的方括号 } // 主解析函数 void parse_json(const char *json) { skip_whitespace(&json); if (*json == '{') { parse_object(&json); } else if (*json == '[') { parse_array(&json); } } int main() { const char *json_str = "{\"name\": \"John\", \"age\": 30}"; parse_json(json_str); return 0; }

#include <stdio.h> #include <stdlib.h> #include <string.h> // 生成 JSON 字符串表示的对象 char *generate_json_object(const char *key, const char *value) { size_t key_len = strlen(key); size_t value_len = strlen(value); size_t json_len = 2 + key_len + 2 + 1 + 2 + value_len + 2; // {} "" : "" char *json = (char *)malloc(json_len); if (json == NULL) { return NULL; } sprintf(json, "{\"%s\": \"%s\"}", key, value); return json; } // 生成 JSON 字符串表示的数组 char *generate_json_array(const char **values, int count) { size_t total_len = 2; // [] for (int i = 0; i < count; i++) { total_len += strlen(values[i]) + 2; // "" if (i < count - 1) { total_len++; // , } } char *json = (char *)malloc(total_len); if (json == NULL) { return NULL; } json[0] = '['; size_t index = 1; for (int i = 0; i < count; i++) { json[index++] = '"'; strcpy(json + index, values[i]); index += strlen(values[i]); json[index++] = '"'; if (i < count - 1) { json[index++] = ','; } } json[index] = ']'; json[index + 1] = '\0'; return json; } int main() { const char *key = "name"; const char *value = "John"; char *json_obj = generate_json_object(key, value); if (json_obj != NULL) { printf("JSON object: %s\n", json_obj); free(json_obj); } const char *values[] = {"apple", "banana", "cherry"}; int count = sizeof(values) / sizeof(values[0]); char *json_arr = generate_json_array(values, count); if (json_arr != NULL) { printf("JSON array: %s\n", json_arr); free(json_arr); } return 0; }

2

{ "employees": [ { "name": "Bob", "department": "Sales", "projects": [ { "projectName": "Project X", "startDate": "2023-01-01" }, { "projectName": "Project Y", "startDate": "2023-06-01" } ] }, { "name": "Eve", "department": "Marketing", "projects": [ { "projectName": "Project Z", "startDate": "2023-03-01" } ] } ] }

下面是解析该 JSON 数据的 C 语言代码:

#include <stdio.h> #include <stdlib.h> #include "cJSON.h" int main() { const char *json_str = "{\"employees\": [{\"name\": \"Bob\", \"department\": \"Sales\", \"projects\": [{\"projectName\": \"Project X\", \"startDate\": \"2023-01-01\"}, {\"projectName\": \"Project Y\", \"startDate\": \"2023-06-01\"}]}, {\"name\": \"Eve\", \"department\": \"Marketing\", \"projects\": [{\"projectName\": \"Project Z\", \"startDate\": \"2023-03-01\"}]}]}"; // 解析 JSON 字符串 cJSON *root = cJSON_Parse(json_str); if (root == NULL) { const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { fprintf(stderr, "Error before: %s\n", error_ptr); } return 1; } // 获取 employees 数组 cJSON *employees = cJSON_GetObjectItem(root, "employees"); if (cJSON_IsArray(employees)) { int array_size = cJSON_GetArraySize(employees); for (int i = 0; i < array_size; i++) { cJSON *employee = cJSON_GetArrayItem(employees, i); cJSON *name = cJSON_GetObjectItem(employee, "name"); cJSON *department = cJSON_GetObjectItem(employee, "department"); if (cJSON_IsString(name) && cJSON_IsString(department)) { printf("Employee Name: %s\n", name->valuestring); printf("Department: %s\n", department->valuestring); } // 获取 projects 数组 cJSON *projects = cJSON_GetObjectItem(employee, "projects"); if (cJSON_IsArray(projects)) { int project_size = cJSON_GetArraySize(projects); printf("Projects:\n"); for (int j = 0; j < project_size; j++) { cJSON *project = cJSON_GetArrayItem(projects, j); cJSON *projectName = cJSON_GetObjectItem(project, "projectName"); cJSON *startDate = cJSON_GetObjectItem(project, "startDate"); if (cJSON_IsString(projectName) && cJSON_IsString(startDate)) { printf(" - Project Name: %s\n", projectName->valuestring); printf(" Start Date: %s\n", startDate->valuestring); } } } printf("\n"); } } // 释放 cJSON 对象占用的内存 cJSON_Delete(root); return 0; } 生成 JSON 数据 下面的代码展示了如何使用 cJSON 库生成一个包含不同数据类型的 JSON 对象: #include <stdio.h> #include <stdlib.h> #include "cJSON.h" int main() { // 创建根 JSON 对象 cJSON *root = cJSON_CreateObject(); if (root == NULL) { fprintf(stderr, "Failed to create JSON object\n"); return 1; } // 添加字符串类型的键值对 cJSON_AddStringToObject(root, "title", "Sample Document"); // 创建嵌套的 author 对象 cJSON *author = cJSON_CreateObject(); if (author == NULL) { fprintf(stderr, "Failed to create author object\n"); cJSON_Delete(root); return 1; } cJSON_AddStringToObject(author, "firstName", "Jane"); cJSON_AddStringToObject(author, "lastName", "Smith"); cJSON_AddItemToObject(root, "author", author); // 创建 tags 数组 cJSON *tags = cJSON_CreateArray(); if (tags == NULL) { fprintf(stderr, "Failed to create tags array\n"); cJSON_Delete(root); return 1; } cJSON_AddItemToArray(tags, cJSON_CreateString("document")); cJSON_AddItemToArray(tags, cJSON_CreateString("sample")); cJSON_AddItemToObject(root, "tags", tags); // 添加数字类型的键值对 cJSON_AddNumberToObject(root, "views", 1234); // 添加布尔类型的键值对 cJSON_AddBoolToObject(root, "isPublished", 1); // 将 JSON 对象转换为字符串 char *json_str = cJSON_Print(root); if (json_str == NULL) { fprintf(stderr, "Failed to print JSON object\n"); cJSON_Delete(root); return 1; } // 打印 JSON 字符串 printf("%s\n", json_str); // 释放内存 free(json_str); cJSON_Delete(root); return 0; }

下面为你展示如何使用 C 语言结合 cJSON 库,以文件形式读写和保存 JSON 数据。我们会提供两个示例,一个是从文件中读取 JSON 数据并解析,另一个是将生成的 JSON 数据保存到文件中。

1. 从文件读取并解析 JSON 数据

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "cJSON.h" // 从文件读取内容到字符串 char* read_file(const char* filename) { FILE* file = fopen(filename, "r"); if (file == NULL) { perror("Failed to open file"); return NULL; } // 获取文件大小 fseek(file, 0, SEEK_END); long size = ftell(file); fseek(file, 0, SEEK_SET); // 分配内存来存储文件内容 char* buffer = (char*)malloc(size + 1); if (buffer == NULL) { perror("Failed to allocate memory"); fclose(file); return NULL; } // 读取文件内容 fread(buffer, 1, size, file); buffer[size] = '\0'; fclose(file); return buffer; } int main() { const char* filename = "input.json"; char* json_str = read_file(filename); if (json_str == NULL) { return 1; } // 解析 JSON 字符串 cJSON* root = cJSON_Parse(json_str); if (root == NULL) { const char* error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { fprintf(stderr, "Error before: %s\n", error_ptr); } free(json_str); return 1; } // 示例:获取并打印 "name" 字段的值 cJSON* name = cJSON_GetObjectItem(root, "name"); if (cJSON_IsString(name)) { printf("Name: %s\n", name->valuestring); } // 释放资源 free(json_str); cJSON_Delete(root); return 0; }

2. 生成 JSON 数据并保存到文件

#include <stdio.h> #include <stdlib.h> #include "cJSON.h" int main() { // 创建根 JSON 对象 cJSON* root = cJSON_CreateObject(); if (root == NULL) { fprintf(stderr, "Failed to create JSON object\n"); return 1; } // 添加键值对 cJSON_AddStringToObject(root, "name", "John Doe"); cJSON_AddNumberToObject(root, "age", 30); // 将 JSON 对象转换为字符串 char* json_str = cJSON_Print(root); if (json_str == NULL) { fprintf(stderr, "Failed to print JSON object\n"); cJSON_Delete(root); return 1; } // 打开文件以写入模式 FILE* file = fopen("output.json", "w"); if (file == NULL) { perror("Failed to open file"); free(json_str); cJSON_Delete(root); return 1; } // 将 JSON 字符串写入文件 fputs(json_str, file); // 关闭文件 fclose(file); // 释放内存 free(json_str); cJSON_Delete(root); return 0; }
标签:

JSON格式,C语言自己实现,以及直接调用库函数(一)由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JSON格式,C语言自己实现,以及直接调用库函数(一)