c语言操作cJson封装,以及json和结构体互转。如果不做封装直接操作cJSON有点儿繁琐。
所以封装下是很有必要的,使用起来简单好用多了。
这是我计划的终端状态监控服务的终端部分的模块组件。
终端应用程序定时更新状态文件,应用中跑的另一个后台服务则定时读取该状态文件并上送至后台服务。以此无耦合的实现对终端的状态监控。参见:终端出厂后自动化运维方案_独行猫A 的沉淀、积累、总结。天天学习,好好向上...linux,Android,Vue,Go)-CSDN博客
下面是c语言读写json文件的简单封装,完成c语言结构体到json文件,json到结构体的转换。
代码语言:javascript复制#include "jsonopt.h"
/**
* Function:GetArrayValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中获取ArrayItem内容
*/
int GetArrayValueString(cJSON* json,int id, char* name, char* param){
cJSON* node;
node = cJSON_GetArrayItem(json,id);
if(!node){
return -1;
}
sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
return 0 ;
}
/**
* Function:GetValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中读取字符串内容
*/
char* GetValueString(cJSON* json,char* name){
cJSON* pObj = NULL;
pObj = cJSON_GetObjectItem(json,name);
if(pObj != NULL){
return pObj->valuestring;
}else{
return NULL;
}
}
/**
* Function:GetValueInt
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中读取int类型值
*/
int GetValueInt(cJSON* json,char* name){
cJSON* pObj = NULL;
pObj = cJSON_GetObjectItem(json,name);
if(pObj != NULL){
return pObj->valueint;
}else{
return 0;
}
}
/**
* Function:SetValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 向json中的String类型字段赋值
*/
int SetValueString(cJSON* json,char* name,char* value){
//printf("set key:%s,val:%sn",name,value);
if(cJSON_GetObjectItem(json,name)->valuestring != NULL){
cJSON_ReplaceItemInObject(json,name,cJSON_CreateString(value));
}else{
//cJSON_AddItemToObject(json, name, cJSON_CreateString(value));
cJSON_AddStringToObject(json, name, value);
}
return 0;
}
/**
* Function:SetValueInt
* Data:2021-11-11
* Author:yangyongzhen
* Description: 向json中的Int类型字段赋值
*/
int SetValueInt(cJSON* json,char* name,int value){
cJSON* pObj = NULL;
pObj = cJSON_GetObjectItem(json,name);
if(pObj != NULL){
pObj->valueint = value;
pObj->valuedouble = value;
return 0;
}else{
cJSON_AddNumberToObject(json, name, value);
}
return 0;
}
代码语言:javascript复制/**
* Copyright (C), 2021-2021,yangyongzhen
* File name: jsonopt.h
* Author: yangyongzhen
* Version: 0.1
* Date: 2021-11-11
* Description: c语言的cJSON操作封装
**/
#ifndef _JSON_OPT_H_
#define _JSON_OPT_H_
#include <string.h>
#include "cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Function:S2J_setInt
* Description:Struct向Json的Int类型赋值
* */
#define S2J_setInt(json,stru,element) SetValueInt(json,#element,(stru)->element)
/**
* Function:S2J_setString
* Description:Struct向Json的String类型赋值
* */
#define S2J_setString(json,stru,element) SetValueString(json,#element,(stru)->element)
/**
* Function:J2S_getString
* Description:Json向Struct中的String类型赋值
* */
#define J2S_getString(json,stru,element) {char *item=NULL; item = GetValueString(json,#element); if(item!=NULL){strcpy((stru)->element,item);}}
/**
* Function:J2S_getInt
* Description:Json向Struct中的Int类型赋值
* */
#define J2S_getInt(json,stru,element) (stru)->element = GetValueInt(json,#element)
/**
* Function:GetArrayValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中获取ArrayItem内容
*/
extern int GetArrayValueString(cJSON* json,int id, char* name, char* param);
/**
* Function:GetValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中读取字符串内容
*/
extern char* GetValueString(cJSON* json,char* name);
/**
* Function:GetValueInt
* Data:2021-11-11
* Author:yangyongzhen
* Description: 从json中读取int类型值
*/
extern int GetValueInt(cJSON* json,char* name);
/**
* Function:SetValueString
* Data:2021-11-11
* Author:yangyongzhen
* Description: 向json中的String类型字段赋值
*/
extern int SetValueString(cJSON* json,char* name,char* value);
/**
* Function:SetValueInt
* Data:2021-11-11
* Author:yangyongzhen
* Description: 向json中的Int类型字段赋值
*/
extern int SetValueInt(cJSON* json,char* name,int value);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
使用方法举例:
代码语言:javascript复制#include "jsonopt.h"
static cJSON* root;
PosStatus posStatus;
/**
从json文件中加载信息到结构体
*/
int LoadStatus(PosStatus *status){
printf("LoadStatus ENTERn");
root = GetJsonObject(STATUS_FILE_NAME);
char * out = cJSON_Print(root);
printf("LoadStatus:json=%sn",out);
if(out == NULL){
printf("LoadStatus error,no json datan");
return -1;
}
J2S_getString(root,status,sn);
printf("[item] = %sn",status->sn);
J2S_getString(root,status,posno);
printf("[item] = %sn",status->posno);
J2S_getString(root,status,city);
printf("[item] = %sn",status->city);
J2S_getString(root,status,tyid);
printf("[item] = %sn",status->tyid);
J2S_getString(root,status,sver);
printf("[item] = %sn",status->sver);
J2S_getString(root,status,ctime);
printf("[item] = %sn",status->ctime);
//item = GetValueString(root,"posno");
//if(item != NULL){
// strcpy(status->posno,item);
// printf("[item] = %sn",status->posno);
//}
return 0;
}
/**
结构体信息保存为json文件
*/
int SaveStatus(PosStatus status){
char * out = NULL;
printf("SaveStatus ENTERn");
if(root == NULL){
printf("SaveStatus errorn");
return -1;
}
S2J_setString(root,&status,sn);
S2J_setString(root,&status,posno);
S2J_setString(root,&status,tyid);
S2J_setString(root,&status,city);
S2J_setString(root,&status,sver);
S2J_setInt(root,&status,unum1);
S2J_setInt(root,&status,unum2);
S2J_setInt(root,&status,amount);
S2J_setInt(root,&status,count);
S2J_setInt(root,&status,line);
S2J_setString(root,&status,carno);
S2J_setString(root,&status,jd);
S2J_setString(root,&status,wd);
S2J_setInt(root,&status,alarm);
S2J_setInt(root,&status,pver);
S2J_setInt(root,&status,bver);
S2J_setString(root,&status,empid);
S2J_setString(root,&status,rvs1);
S2J_setString(root,&status,rvs2);
S2J_setString(root,&status,stime);
S2J_setString(root,&status,ctime);
S2J_setInt(root,&status,tenant);
//SetValueString(root,"carno",status.carno);
//SetValueString(root,"jd",status.jd);
//SetValueString(root,"wd",status.wd);
printf("SaveStatus endn");
out = cJSON_Print(root);
writeFile(STATUS_FILE_NAME,out);
printf("SetStatus:json=%sn",out);
return 0;
}
代码语言:javascript复制//status.h头文件
#ifndef _STATUS_H_
#define _STATUS_H_
#include "cJSON/cJSON.h"
//保存位置 终端状态监控文件存储位置
#define STATUS_FILE_NAME "../opt/status.json"
//#define STATUS_FILE_NAME "./status.json"
//终端设备状态信息
typedef struct _PosStatus{
char sn[32]; //设备唯一号
char posno[16]; //终端编号
char city[10]; //城市代码
char tyid[10]; //终端类型
char sver[32]; //终端版本号
int unum1; //未传记录数量--公交
int unum2; //未传记录数量--三方
char ndate[16]; //当前日期
char ntime[16]; //当前时间
int amount; //当班总额
int count; //当班人数
int line; //线路号
char carno[16]; //车辆编号
char jd[20]; //经度
char wd[20]; //维度
int alarm; //设备报警码
char stime[16]; //开机时间
char ctime[16]; //关机时间
int tenant; //租户ID
}PosStatus;
extern PosStatus posStatus;
extern int LoadStatus(PosStatus *status);
extern int SaveStatus(PosStatus status);
extern int SetValueInt(cJSON* root,char* name,int value);
extern int SetValueString(cJSON* root,char* name,char* value);
extern char* GetValueString(cJSON* json,char* name);
extern int GetValueInt(cJSON* json,char* name);
extern cJSON* GetJsonObject(char* fileName);
extern int writeFile(char *filename,char *data);
#endif
static.c文件内容:
代码语言:javascript复制#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "status.h"
static cJSON* root;
PosStatus posStatus;
/**
从文件中读取json信息到结构体
*/
int LoadStatus(PosStatus *status){
root = GetJsonObject(STATUS_FILE_NAME);
char * out = cJSON_Print(root);
printf("LoadStatus:json=%sn",out);
if(out == NULL){
printf("LoadStatus error,no json datan");
return -1;
}
char * item = NULL;
item = GetValueString(root,"sn");
if(item != NULL){
strcpy(status->sn,item);
printf("[item] = %sn",status->sn);
}
item = GetValueString(root,"posno");
if(item != NULL){
strcpy(status->posno,item);
printf("[item] = %sn",status->posno);
}
item = GetValueString(root,"city");
if(item != NULL){
strcpy(status->city,item);
printf("[item] = %sn",status->city);
}
item = GetValueString(root,"tyid");
if(item != NULL){
strcpy(status->tyid,item);
printf("[item] = %sn",status->tyid);
}
item = GetValueString(root,"sver");
if(item != NULL){
strcpy(status->sver,item);
printf("[item] = %sn",status->sver);
}
return 0;
}
/**
结构体信息写入json文件
*/
int SaveStatus(PosStatus status){
char * out = NULL;
printf("SaveStatus ENTERn");
if(root == NULL){
printf("SaveStatus errorn");
return -1;
}
SetValueString(root,"sn",status.sn);
SetValueString(root,"posno",status.posno);
SetValueString(root,"tyid",status.tyid);
SetValueString(root,"city",status.city);
SetValueString(root,"sver",status.sver);
SetValueInt(root,"unum1",status.unum1);
SetValueInt(root,"unum2",status.unum2);
SetValueInt(root,"amount",status.amount);
SetValueInt(root,"count",status.count);
SetValueInt(root,"line",status.line);
SetValueString(root,"carno",status.carno);
SetValueString(root,"jd",status.jd);
SetValueString(root,"wd",status.wd);
SetValueInt(root,"alarm",status.alarm);
SetValueString(root,"stime",status.stime);
SetValueString(root,"ctime",status.ctime);
SetValueInt(root,"tenant",status.tenant);
out = cJSON_Print(root);
writeFile(STATUS_FILE_NAME,out);
printf("SetStatus:json=%sn",out);
return 0;
}
int writeFile(char *filename,char *data){
FILE *fp = NULL;
fp = fopen(filename,"w ");
if(fp == NULL){
fprintf(stderr,"open file failedn");
return -1;
}
fprintf(fp,"%s",data);
if(fp != NULL){
fclose(fp);
}
return 0;
}
cJSON* GetJsonObject(char* fileName){
long len;
char* pContent;
int tmp;
cJSON* json;
FILE* fp = fopen(fileName, "rb ");
if(!fp){
printf("open file errorn");
return NULL;
}
printf("open file successn");
fseek(fp,0,SEEK_END);
len=ftell(fp);
if(0 == len){
printf("file len is 0n");
return NULL;
}
fseek(fp,0,SEEK_SET);
pContent = (char*) malloc (sizeof(char)*len);
tmp = fread(pContent,1,len,fp);
fclose(fp);
json = cJSON_Parse(pContent);
if (!json)
{
free(pContent);
return NULL;
}
free(pContent);
printf("read file okn");
return json;
}
//读取cJSON索引为index的结点某个key值对应的value,索引从0开始
int GetArrayValueString(cJSON* json,int id, char* name, char* param){
cJSON* node;
node = cJSON_GetArrayItem(json,id);
if(!node){
return -1;
}
sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
return 0 ;
}
char* GetValueString(cJSON* json,char* name){
cJSON* pObj = NULL;
pObj = cJSON_GetObjectItem(json,name);
if(pObj != NULL){
return pObj->valuestring;
}else{
return NULL;
}
}
int GetValueInt(cJSON* json,char* name){
cJSON* pObj = NULL;
pObj = cJSON_GetObjectItem(json,name);
if(pObj != NULL){
return pObj->valueint;
}else{
return 0;
}
}
int SetValueString(cJSON* json,char* name,char* value){
strcpy(cJSON_GetObjectItem(json,name)->valuestring,value);
return 0;
}
int SetValueInt(cJSON* json,char* name,int value){
cJSON_GetObjectItem(json,name)->valueint = value;
cJSON_GetObjectItem(json,name)->valuedouble = value;
return 0;
}
/*
int main(){
printf("cjson test,read and saven");
LoadStatus(&posStatus);
strcpy(posStatus.sver,"NC_B503_YYZ");
posStatus.alarm = 6;
posStatus.amount = 10;
posStatus.count = 12;
strcpy(posStatus.posno,"413101010E");
SaveStatus(posStatus);
}
*/
生成的json文件如:
代码语言:javascript复制{
"sn": "00a0c6000023",
"posno":"413101010E",
"city": "",
"tyid": "",
"sver": "NC_B503_YYZ",
"unum1": 0,
"unum2": 0,
"ndate": "2021-08-11",
"ntime": "17:20:30",
"amount": 10,
"count": 12,
"line": 0,
"carno": "",
"jd": "",
"wd": "",
"alarm": 6,
"stime": "",
"ctime": "",
"tenant": 0
}
附带一个终端开机自启动脚本startmonitor.sh:
代码语言:javascript复制#!/bin/bash
fileName="/app/city_app/opt/monitor"
buzzGPIO="/sys/class/gpio/gpio15"
#enable buzzse for notifying success
function beep_notify()
{
if [ ! -d "$buzzGPIO" ]; then
echo 15 > /sys/class/gpio/export
fi
if [ -d "$buzzGPIO" ]; then
echo "out" > "/sys/class/gpio/gpio15/direction"
echo "1" > "/sys/class/gpio/gpio15/value"
sleep 1
echo "0" > "/sys/class/gpio/gpio15/value"
fi
}
function CheckProcess()
{
PROCESS_NUM=`ps | grep "$1" | grep -v "grep" | wc -l`
return $PROCESS_NUM
}
if [ ! -f $fileName ]; then
echo "error!monitor file not exit!"
exit 1
else
echo "find monitor file,begin start..."
CheckProcess qrlinux
if [ $? -eq 0 ];then
echo "no monitor progress find!"
else
echo "find monitor,..."
killall -9 monitor
sleep 1
fi
cd /app/city_app/opt/
./monitor -monitorcfg=./monitorcfg.ini &
echo "start ok"
beep_notify
exit 0
fi
终端开机自启动服务应用的方法:
代码语言:javascript复制system("killall -9 monitor");
system("../opt/startmonitor.sh");