cJSON 及 c文件操作

介绍 JSON:https://www.json.org/json-zh.html

cJSON Github:https://github.com/DaveGamble/cJSON

JSON在线解析工具:http://www.json.org.cn/tools/JSONEditorOnline/index.htm


cJson库中提供了非常多接口函数供我们使用,这里记录cJSON与C语言的文件操作的示例。

1. 读取json文件

从json中读取文件,返回包含文件内容的字符串,注意使用该函数后需要手动释放

/* 读取json文件 */
const char* ReadJson(const char* filename)
{
	FILE* fp = NULL;
	long len = 0;
	char* data = NULL;

	fp = fopen(filename, "rb");	/* 打开文件 */
	fseek(fp, 0, SEEK_END);		/* 设置文件指针位置——SEEK_END,文件末尾 */
	len = ftell(fp);			/* 计算当前文件指针位置到文件起始位置的偏移 */
	fseek(fp, 0, SEEK_SET);		/* 设置文件指针位置——SEEK_SET,文件起始位置 */
	data = (char*)malloc(len + 1);/* 申请空间存放数据,读取文件数据存储至该buff中 */
	fread(data, 1, len, fp);	/* 从文件中读取数据,存放在data所指向的buff中 */
	fclose(fp);					/* 关闭文件指针 */
	//free(data);				/* 释放data所指向的malloc空间 */
	return data;
}
2. 保存文件
  • 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。即将我们对象中的数据转化为易于传输的字节流形式。
  • 反序列化,是序列化的逆过程。即,将字符串流转换为对象。

使用序列化的 json 数据构建 json 对象需要使用 cJSON_Parse() 函数。

/* 保存 普通字符串 到文本文件 */
void SaveText(const char* text, const char* name)
{
	FILE* fp = fopen(name, "w");
	if (NULL != fp)
	{
		fwrite(text, strlen(text), 1, fp);	/* 保存到文件 */
		// fputs(buff,fp);
		fclose(fp);				/* 关闭文件指针 */
	}
	else perror("open text.json error!\n");
}
/* 将文本处理成json格式后保存 */
void Save_TextToJSON(const char *text, const char* name)
{
	cJSON* json;

	json = cJSON_Parse(text);		/* 从json字符串中得到cjson对象 */
	if (!json) {
		printf("Error before: [%s]\n", cJSON_GetErrorPtr());
	}

	char* buff = cJSON_Print(json);	/* 将json对象转化为打印的格式 */

	SaveText(buff, name);	/* 保存到文件 */

	cJSON_Delete(json);		/* 释放json对象 */
	free(buff);				/* 释放buff字符串 */
}
测试代码
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"

#pragma warning(disable:4996)



/* 将文本解析为JSON格式,并打印 */
void Show(char *text)
{
	cJSON *json = cJSON_Parse(text);		/* 从json字符串中得到cjson对象 */

	if (!json) {	
		printf("Error before: [%s]\n",cJSON_GetErrorPtr());
	}

	char* out=cJSON_Print(json);/* 将json对象转化为打印的格式 */
	printf("%s\n",out);		/* 将格式化的json数据打印在屏幕上 */
	cJSON_Delete(json);		/* 释放json对象 */
	free(out);				/* 释放out字符串 */

}



/* 读取json文件 */
const char* ReadJson(const char* filename)
{
	FILE* fp = NULL;
	long len = 0;
	char* data = NULL;

	fp = fopen(filename, "r");	/* 打开文件 */
	fseek(fp, 0, SEEK_END);		/* 设置文件指针位置——SEEK_END,文件末尾 */
	len = ftell(fp);			/* 计算当前文件指针位置到文件起始位置的偏移 */
	fseek(fp, 0, SEEK_SET);		/* 设置文件指针位置——SEEK_SET,文件起始位置 */
	data = (char*)malloc(len + 1);/* 申请空间存放数据,读取文件数据存储至该buff中 */
	fread(data, 1, len, fp);	/* 从文件中读取数据,存放在data所指向的buff中 */
	fclose(fp);					/* 关闭文件指针 */
	//free(data);				/* 释放data所指向的malloc空间 */
	return data;
}

/* 保存 普通字符串 到文本文件 */
void SaveText(const char* text, const char* name)
{
	FILE* fp = fopen(name, "w");
	if (NULL != fp)
	{
		fwrite(text, strlen(text), 1, fp);	/* 保存到文件 */
		// fputs(buff,fp);
		fclose(fp);				/* 关闭文件指针 */
	}
	else perror("open text.json error!\n");
}
/* 将文本处理成json格式后保存 */
void Save_TextToJSON(const char *text, const char* name)
{
	cJSON* json;

	json = cJSON_Parse(text);		/* 从json字符串中得到cjson对象 */
	if (!json) {
		printf("Error before: [%s]\n", cJSON_GetErrorPtr());
	}

	char* buff = cJSON_Print(json);	/* 将json对象转化为打印的格式 */

	SaveText(buff, name);	/* 保存到文件 */

	cJSON_Delete(json);		/* 释放json对象 */
	free(buff);				/* 释放buff字符串 */
}


int main () 
{

	char text[] = 
		"{\"name\":\"JSON中国\",\"url\":\"http://www.json.org.cn\",\"page\":88,\"isNonProfit\":true,\"address\":{\"street\":\"浙大路38号.\",\"city\":\"浙江杭州\",\"country\":\"中国\"},\"links\":\
	[{\"name\":\"Google\",\"url\":\"http://www.google.com\"},{\"name\":\"Baidu\",\"url\":\"http://www.baidu.com\"},{\"name\":\"SoSo\",\"url\":\"http://www.SoSo.com\"}]}";
	//printf("%s\n", text);		// 输出text内容到屏幕
	SaveText(text, "text.txt");	// 保存text内容到文本
	
	//Show(text);	// 将text内容,以json格式的“视图”打印

	Save_TextToJSON(text, "text.json");// 解析json字符串,并保存为json格式的文件

	// 读取json文件,data是json格式化数据
	const char* data = ReadJson(".\\text.json");// 路径使用 '/'或'\\'都可以 //free
	cJSON* pjson = cJSON_Parse(data);		// 使用json数据构建cJSON对象

	char* p = cJSON_Print(pjson);											// free
	printf("%s\n", p);
	const char* out = cJSON_PrintUnformatted(pjson);// 不使用格式化的打印	// free
	printf("%s\n", out);

	cJSON_Delete(pjson);
	free(data);
	free(p);
	free(out);
	return 0;
}

cJSON头文件中提供的接口函数。

#ifndef cJSON__h
#define cJSON__h

#ifdef __cplusplus
extern "C"
{
#endif

	/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

#define cJSON_IsReference 256

/* The cJSON structure: */
	typedef struct cJSON {
		struct cJSON* next, * prev;	/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
		struct cJSON* child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

		int type;					/* The type of the item, as above. */

		char* valuestring;			/* The item's string, if type==cJSON_String */
		int valueint;				/* The item's number, if type==cJSON_Number */
		double valuedouble;			/* The item's number, if type==cJSON_Number */

		char* string;				/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
	} cJSON;

	typedef struct cJSON_Hooks {
		void* (*malloc_fn)(size_t sz);
		void (*free_fn)(void* ptr);
	} cJSON_Hooks;

	/* Supply malloc, realloc and free functions to cJSON */
	extern void cJSON_InitHooks(cJSON_Hooks* hooks);


	/* 提供一个JSON块,这会返回一个可以查询的cJSON对象。完成后调用cJSON Delete */
	extern cJSON* cJSON_Parse(const char* value);
	/* 将一个cJSON实体渲染为文本以便传输/存储。完成时释放char* */
	extern char* cJSON_Print(cJSON* item);
	/* 将cJSON实体呈现为文本以进行传输/存储,而无需进行任何格式设置。 完成后释放字符*。 */
	extern char* cJSON_PrintUnformatted(cJSON* item);
	/* 删除一个cJSON实体和所有子实体。 */
	extern void   cJSON_Delete(cJSON* c);

	/* 返回数组(或对象)中项目的数量。 */
	extern int	  cJSON_GetArraySize(cJSON* array);
	/* 从数组“array”中检索项目编号“item”。如果不成功则返回NULL。 */
	extern cJSON* cJSON_GetArrayItem(cJSON* array, int item);
	/* 从object中获取item "string"。不区分大小写。 */
	extern cJSON* cJSON_GetObjectItem(cJSON* object, const char* string);

	/* 用于分析失败的分析。 这将返回一个指向解析错误的指针。 您可能需要回顾一些字符才能理解它。
		 在cJSON_Parse()返回0时定义。当cJSON_Parse()成功时为0。 */
	extern const char* cJSON_GetErrorPtr(void);

	/* 这些调用创建一个适当类型的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);
	extern cJSON* cJSON_CreateArray(void);
	extern cJSON* cJSON_CreateObject(void);

	/* 这些实用程序创建一个计数项数组。 */
	extern cJSON* cJSON_CreateIntArray(int* numbers, int count);
	extern cJSON* cJSON_CreateFloatArray(float* numbers, int count);
	extern cJSON* cJSON_CreateDoubleArray(double* numbers, int count);
	extern cJSON* cJSON_CreateStringArray(const char** strings, int count);

	/* 将项目追加到指定的数组/对象。 */
	extern void cJSON_AddItemToArray(cJSON* array, cJSON* item);
	extern void	cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item);
	/* 将对项目的引用附加到指定的数组/对象。 当您要将现有的cJSON添加到新的cJSON,但又不想破坏现有的cJSON时,请使用此选项。 */
	extern void cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item);
	extern void	cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item);

	/* 从数组/对象中移除/移除项。 */
	extern cJSON* cJSON_DetachItemFromArray(cJSON* array, int which);	// 返回分离的项目
	extern void   cJSON_DeleteItemFromArray(cJSON* array, int which);	// 删除分离的项目。
	extern cJSON* cJSON_DetachItemFromObject(cJSON* object, const char* string);
	extern void   cJSON_DeleteItemFromObject(cJSON* object, const char* string);

	/* 更新数组项。 */
	extern void cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem);
	extern void cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem);

	/* 复制一个cJSON项 */
	extern cJSON* cJSON_Duplicate(cJSON* item, int recurse);
	/* Duplicate将在新的内存中创建一个与你传递的cJSON项相同的新cJSON项需要被释放。递归!=0时,它将复制连接到该项目的任何子节点。
		在从Duplicate返回时,item->next和->prev指针总是0。 */

	/* ParseWithOpts允许您要求(并检查)JSON是否以null结尾,并检索指向已解析的最终字节的指针。 */
	extern cJSON* cJSON_ParseWithOpts(const char* value, const char** return_parse_end, int require_null_terminated);

	/* 用于快速创建事物的宏。 */
#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))

/* 当分配一个整数值时,它也需要传播到valueddouble。 */
#define cJSON_SetIntValue(object,val)			((object)?(object)->valueint=(object)->valuedouble=(val):(val))

#ifdef __cplusplus
}
#endif

#endif

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫RT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值