C语言中如何保存JSON文件:实用指南与代码示例
在C语言开发中,处理JSON数据是常见需求,尤其是在需要将结构化数据持久化存储的场景(如配置文件、数据导出等),本文将详细介绍如何使用C语言操作JSON文件,包括选择合适的JSON库、数据编码、文件写入及错误处理,并提供完整代码示例。
为什么需要JSON库?JSON文件保存的核心步骤
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,以易读的文本形式存储和传输数据,C语言本身没有内置JSON支持,因此需要借助第三方库来解析、生成和操作JSON数据,保存JSON文件的核心步骤包括:
- 定义数据结构:将需要保存的数据用C语言结构体或变量表示;
- 编码为JSON格式:使用JSON库将C数据转换为JSON格式的字符串;
- 写入文件:将JSON字符串保存到本地文件(如
.json文件); - 错误处理:检查编码和文件操作是否成功,确保数据完整性。
选择合适的JSON库
C语言常用的JSON库包括:
- cJSON:轻量级、单文件、易集成,支持JSON的解析和生成,适合中小型项目;
- Jansson功能更丰富,支持严格JSON规范,适合复杂场景;
- ujson:高性能,适合对速度要求极高的场景。
本文以cJSON为例(因其简单易用,社区活跃),演示JSON文件的保存流程。
使用cJSON保存JSON文件的完整流程
环境准备:下载并集成cJSON库
从cJSON官方GitHub下载最新版本,或直接将cJSON.h和cJSON.c文件添加到项目中,编译时需链接cJSON.c,
gcc your_program.c cJSON.c -o your_program -lm
定义数据结构
假设我们需要保存一个用户信息,包含姓名、年龄、是否激活和爱好列表,用C结构体表示如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
typedef struct {
char name[50];
int age;
int is_active;
char hobbies[3][20]; // 假设最多3个爱好
} User;
创建JSON对象并填充数据
cJSON通过层级结构表示JSON数据,使用cJSON_CreateXxx()系列函数创建节点,用cJSON_AddXxxToObject()添加到父对象。
示例:将User结构体转换为JSON对象
cJSON* create_user_json(const User* user) {
// 创建根对象(JSON对象)
cJSON* root = cJSON_CreateObject();
if (!root) {
fprintf(stderr, "Failed to create root JSON object\n");
return NULL;
}
// 添加字符串字段:name
cJSON_AddStringToObject(root, "name", user->name);
// 添加数字字段:age
cJSON_AddNumberToObject(root, "age", user->age);
// 添加布尔字段:is_active
cJSON_AddBoolToObject(root, "is_active", user->is_active);
// 创建hobbies数组
cJSON* hobbies_array = cJSON_CreateArray();
if (!hobbies_array) {
fprintf(stderr, "Failed to create hobbies array\n");
cJSON_Delete(root);
return NULL;
}
cJSON_AddItemToObject(root, "hobbies", hobbies_array);
// 向数组添加元素
for (int i = 0; i < 3; i++) {
if (strlen(user->hobbies[i]) > 0) { // 仅添加非空爱好
cJSON_AddItemToArray(hobbies_array, cJSON_CreateString(user->hobbies[i]));
}
}
return root;
}
将JSON对象转换为字符串
cJSON提供了cJSON_Print()和cJSON_PrintUnformatted()函数将JSON对象转为字符串。cJSON_Print()会格式化输出(带缩进),便于阅读;cJSON_PrintUnformatted()输出紧凑字符串(节省空间)。
char* json_to_string(cJSON* json, int formatted) {
if (formatted) {
return cJSON_Print(json); // 格式化输出,如:{"name": "Alice", "age": 25}
} else {
return cJSON_PrintUnformatted(json); // 紧凑输出,如:{"name":"Alice","age":25}
}
}
将JSON字符串写入文件
使用标准文件操作(fopen、fwrite、fclose)将字符串写入文件,注意:
- 文件以文本模式("w")打开,确保JSON字符串正确写入;
- 检查文件操作是否成功(如磁盘空间不足、权限问题);
- 释放JSON字符串内存(
cJSON_free)。
int save_json_to_file(const char* filename, const char* json_str) {
FILE* fp = fopen(filename, "w");
if (!fp) {
fprintf(stderr, "Failed to open file: %s\n", filename);
return -1;
}
size_t len = strlen(json_str);
size_t written = fwrite(json_str, 1, len, fp);
fclose(fp);
if (written != len) {
fprintf(stderr, "Failed to write complete JSON to file\n");
return -1;
}
return 0; // 成功
}
完整示例代码
将上述步骤整合,完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
typedef struct {
char name[50];
int age;
int is_active;
char hobbies[3][20];
} User;
cJSON* create_user_json(const User* user) {
cJSON* root = cJSON_CreateObject();
if (!root) return NULL;
cJSON_AddStringToObject(root, "name", user->name);
cJSON_AddNumberToObject(root, "age", user->age);
cJSON_AddBoolToObject(root, "is_active", user->is_active);
cJSON* hobbies_array = cJSON_CreateArray();
cJSON_AddItemToObject(root, "hobbies", hobbies_array);
for (int i = 0; i < 3; i++) {
if (strlen(user->hobbies[i]) > 0) {
cJSON_AddItemToArray(hobbies_array, cJSON_CreateString(user->hobbies[i]));
}
}
return root;
}
char* json_to_string(cJSON* json, int formatted) {
return formatted ? cJSON_Print(json) : cJSON_PrintUnformatted(json);
}
int save_json_to_file(const char* filename, const char* json_str) {
FILE* fp = fopen(filename, "w");
if (!fp) return -1;
size_t len = strlen(json_str);
size_t written = fwrite(json_str, 1, len, fp);
fclose(fp);
return (written == len) ? 0 : -1;
}
int main() {
// 1. 准备数据
User user = {
.name = "Alice",
.age = 25,
.is_active = 1,
.hobbies = {"reading", "coding", "traveling"}
};
// 2. 创建JSON对象
cJSON* json_obj = create_user_json(&user);
if (!json_obj) {
fprintf(stderr, "Failed to create JSON object\n");
return EXIT_FAILURE;
}
// 3. 转换为格式化字符串
char* json_str = json_to_string(json_obj, 1); // 1表示格式化
if (!json_str) {
fprintf(stderr, "Failed to convert JSON to string\n");
cJSON_Delete(json_obj);
return EXIT_FAILURE;
}
// 4. 打印JSON字符串(可选)
printf("Generated JSON:\n%s\n", json_str);
// 5. 保存到文件
const char* filename = "user.json";
if (save_json_to_file(filename, json_str) == 0) {
printf("JSON saved to %s successfully\n", filename);
} else {
fprintf(stderr, "Failed to save JSON to file\n");
}
// 6. 释放内存
cJSON_free(json_str);
cJSON_Delete(json_obj);
return EXIT_SUCCESS;
}
运行结果与输出
执行上述代码后,当前目录下会生成user.json如下(格式化输出):
{
"name": "Alice",
"age": 25,
"is_active": true,
"hobbies": [
"reading",
"coding",
"traveling"
]
}
错误处理与注意事项
- 内存管理:
- cJSON对象和字符串需要手动释放:
cJSON_Delete()释放JSON对象,cJSON_free()释放`c
- cJSON对象和字符串需要手动释放:



还没有评论,来说两句吧...