json解析

Shell、cJSON读取json文件

使用 shell 命令进行读取

json文件example.txt的例子:

{
	"err_code":200,
	"err_msg":"this is no error",
	"status":1,
	"dev_name":"mylinux",
	"dev_id":123,
	"code": [{"test":89}]
}

使用 sed 命令读取

优点在于,即使 json 文件出现错误,还是可以读取出其他的内容

# s代表 substitute 表示替换
sed 's/原字符串/替换字符串/'
# 获取变量对应的值
cat example.txt | sed 's/,/\n/g' | grep "dev_id" | sed 's/:/\n/g' | sed '1d' | sed 's/}//g'

# - 第一个 sed 命令的意思是将 "," 号,全部换成 "\n"
# - 第二个 grep 命令是将 "dev_id" 关键字查找出来,并单列出来
# - 第三个 sed 命令是将 ":" 号换成 "\n" 符号
# - 第四个 sed 命令是将第一行删除掉,也就是 "dev_id" 这一行
# - 第五个 sed 命令就是将 "}" 符号给删除掉

# 将获取到的值存放进入json文件中
dev_id=$(cat example.txt | sed 's/,/\n/g' | grep "dev_id" | sed 's/:/\n/g' | sed '1d' | sed 's/}//g')
echo $dev_id

使用 jq 命令读取

# 安装 jq 
sudo apt install jq

# 使用 jq
cat example.txt | jq '.'  # 取出 example.txt 文件中的全部内容
cat example.txt | jq -r '.err_code' # 取出 err_code 值

# 获取数组的命令
cat example.txt | jq -r '.code[0].test' # 取出数组第一个 object 中键为 test 的值

err_code = $(cat example.txt | jq -r '.err_code')   # 取出 err_code 值 赋值给 err_code 变量
echo $err_code

使用 cjson 进行读取

cjson的获取

cjson 开源网址:https://sourceforge.net/projects/cjson/

只需要将 cJSON.ccJSON.h 两个文件拷贝到自己的项目中即可,在linuxwindows下面都是可以使用的。

cjson的使用

json的格式是使用键值对的形式:"name": "libia" , 那么其中的name就是键,libia就是值。使用{} 花括号表示对象,使用[]表示数组。

{ "name": "张三", "age": 18, "city": "北京"}
[ {"name":"123"},{"kl":"234"},"kask":23 ]

cJSON结构体

typedef struct cJSON {
	struct cJSON *next,*prev;	/* next是获取下一个元素数据,prev是获取前一个元素数据 */
	struct cJSON *child; /* 获取第一个元素数据*/
	int type;	/* 当前的json类型对象、数组、字符串、数字、null、true、false等 */
	char *valuestring;	/* 字符串值, if type==cJSON_String */
	int valueint;	/* 整形类型值, if type==cJSON_Number */
	double valuedouble;	/* 浮点数类型值, if type==cJSON_Number */

	char *string;				/* 这个是键 */
} cJSON;

/* cJSON Types: */
#define cJSON_False 0		// true
#define cJSON_True 1		// false
#define cJSON_NULL 2		// NULL
#define cJSON_Number 3		// 数字
#define cJSON_String 4		// 字符串
#define cJSON_Array 5		// 数组
#define cJSON_Object 6		// 对象

字符串和cJSON对象相互转换

/* 通过字符串获取cJSON root 对象 */
extern cJSON *cJSON_Parse(const char *value);
/* 释放cJSON_Parse返回的指针 */
extern void   cJSON_Delete(cJSON *c);

/* 通过cJSON指针生成对应的字符串并进行格式化 */
extern char  *cJSON_Print(cJSON *item);
/* 这个相对于上面来说是没有进行格式化,为一行显示 */
extern char  *cJSON_PrintUnformatted(cJSON *item);

封装JSON

/* 创建各种JSON对象 */
/* Create basic types: */
cJSON *cJSON_CreateNull(void)
cJSON *cJSON_CreateTrue(void)
cJSON *cJSON_CreateFalse(void)
cJSON *cJSON_CreateBool(int b)
cJSON *cJSON_CreateNumber(double num)
cJSON *cJSON_CreateString(const char *string)
cJSON *cJSON_CreateArray(void)
cJSON *cJSON_CreateObject(void)
    
/* 创建各种类型的数组,并进行初始化 */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
int nums = {1,2,3,4,5};
cJSON *num_arry = cJSON_CreateIntArray(nums, 5); // [1,2,3,4,5,6]
    
/*添加对象到数组或者对象中*/
void   cJSON_AddItemToArray(cJSON *array, cJSON *item);
cJSON_AddItemToArray(array1, cJSON_CreateString("篮球"));
// [....,"篮球"]
void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
cJSON_AddItemToObject(root, "basketball", cJSON_CreateString("篮球"));
// {.....,"basketball":"篮球"}

/*释放cJSON指针*/
void cJSON_Delete(cJSON *c);  // cJSON_Delete(root);

解析JSON

/* Returns the number of items in an array (or object). */
/* 获取数组中节点的个数 */
extern int	  cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
/* 获取数组中的第item个数据,索引从0开始 */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
/* 获取对象中键相对应的值的JSON */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
  • 解析示例
/*示例json*/
{ 
    "adc": {
        "篮球":1,
        "足球":2
    }
}

/*代码编写*/
/*************** 方式一 ***************/
item = cJSON_GetObjectItem(root, "adc");
if (item != NULL) {
	cJSON *val = NULL;
	val = cJSON_GetObjectItem(item, "篮球");
	if (val != NULL && val->type == cJSON_Number) {
		v_str = val->valueint;
	}

	val = cJSON_GetObjectItem(item, "足球");
		if (val != NULL && val->type == cJSON_Number) {
			v_str = val->valueint;
		}
	}
}

/*************** 方式二 ***************/
item = cJSON_GetObjectItem(root, "interest");
if (item != NULL) {
	cJSON *obj = item->child;	// 获得 "篮球":1
	while (obj) {
		if (obj->type == cJSON_Number) {
			char *v_str = obj->valueint;
		}
		// 获取下一个元素
		obj = obj->next;
	}
}

/*示例json*/
{
    "name":["lili","lishs","jskjkj"]
}

/*代码编写*/
/*************** 方式一 ***************/
char *v_str[3];
item = cJSON_GetObjectItem(root, "name");
if (item != NULL) {
	int size = cJSON_GetArraySize(item);	// 获得数组个数
    int i = 0;
    for(i = 0; i < size; i++){
        cJSON *arr = cJSON_GetArrayItem(item, i);	// 根据索引获得数组中的值
        
        if(arr != NULL && arr->type == cJSON_String){
            v_str[i] = arr->valuestring;
        }
    }
}

/*************** 方式二 ***************/
item = cJSON_GetObjectItem(root, "name");
if (item != NULL) {
	cJSON *obj = item->child;	// 获得 "lili"
	while (obj) {
		if (obj->type == cJSON_String) {
			char *v_str = obj->valuestring;
		}
		// 获取下一个元素
		obj = obj->next;
	}
}

修改JSON

/* 数组中插入元素,在which位置处,索引从0开始 */
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem);
cJSON *new_ele = cJSON_CreateInt(3);
cJSON_InsertItemInArray(arr, 2, new_ele);
/* 更改数组索引为which的值为newitem */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
cJSON_ReplaceItemInArray(item, 0, cJSON_CreateString("red")); 
/* 更改对象里面键为string的值为newitem */
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
cJSON_ReplaceItemInArray(item, cJSON_CreateString("green"));

删除JSON

/* 删除数组索引为which的键值对对象或者数据 */
extern void   cJSON_DeleteItemFromArray(cJSON *array,int which);
cJSON_DeleteItemFromArray(item, 0);
/* 删除对象中的键为string的键值对对象 */
extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
cJSON_DeleteItemFromArray(item, "name");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值