jsoncpp解决序列化顺序按字母排序问题
json
适用于现代 C++ 的 JSON。
项目地址:https://gitcode.com/gh_mirrors/js/json
免费下载资源
·
使用场景:需要修改json中key的值,如果使用jsoncpp读取——序列化——修改值——存储,这样的话存的json文件的关键字的顺序就和源文件不是一致的,默认会按照字母进行排序。
使用jsoncpp没有找到合适的方式进行解决,只能借助python进行解决。
python可以指定顺序,在之前已经介绍过:python 读取json格式数据保持原有顺序
我们可以在c++中调用python的函数进行这个操作。
python代码如下:
#! /usr/bin/python2.7
# -*- coding:utf-8 -*-
import json
from collections import OrderedDict
#返回值 -1表示key不存在
#返回值 -2表示打开源文件失败
#返回值 -3表示打开更新文件失败
#返回值 0表示更新成功
def updateJson(jsonFile,jsonNewData,*jsonKey):
try:
f = open(jsonFile, "r")
except IOError:
return -2
jsonFileData = json.load(f,object_pairs_hook=OrderedDict)
#print(json.dumps(jsonFileData,indent = 4))
jsonKey = list(jsonKey)
jsonKeyLen = len(jsonKey)
keyExist = True
#匹配key是否存在
for i in range(jsonKeyLen):
if i == 0:
if jsonKey[i] not in jsonFileData:
keyExist = False
break
else:
if jsonKey[i] not in jsonFileData[jsonKey[i-1]]:
keyExist = False
break
if keyExist == False:
f.close()
return -1
if jsonKeyLen == 1:
jsonFileData[jsonKey[0]] = jsonNewData
elif jsonKeyLen == 2:
jsonFileData[jsonKey[0]][jsonKey[1]] = jsonNewData
elif jsonKeyLen == 3:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]] = jsonNewData
elif jsonKeyLen == 4:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]] = jsonNewData
elif jsonKeyLen == 5:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]] = jsonNewData
elif jsonKeyLen == 6:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]][jsonKey[5]] = jsonNewData
elif jsonKeyLen == 7:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]][jsonKey[5]][jsonKey[6]] = jsonNewData
elif jsonKeyLen == 8:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]][jsonKey[5]][jsonKey[6]][jsonKey[7]] = jsonNewData
elif jsonKeyLen == 9:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]][jsonKey[5]][jsonKey[6]][jsonKey[7]][jsonKey[8]] = jsonNewData
elif jsonKeyLen == 10:
jsonFileData[jsonKey[0]][jsonKey[1]][jsonKey[2]][jsonKey[3]][jsonKey[4]][jsonKey[5]][jsonKey[6]][jsonKey[7]][jsonKey[8]][jsonKey[9]] = jsonNewData
f.close()
try:
f2 = open(jsonFile, "w")
except IOError:
return -3
jsonStr = json.dumps(jsonFileData,indent = 4)
#print(jsonStr)
f2.write(jsonStr)
f2.close()
return 0
if __name__ == "__main__":
print(updateJson("78911.json",False,"openFlag"))
print(updateJson("789.json",False,"openFlag22"))
print(updateJson("789.json",60,"ID"))
print(updateJson("789.json","blue","color","book"))
print(updateJson("789.json",False,"openFlag"))
目前这个函数只能修改10层内嵌套key的json,而且采用了一个比较蠢的方法,就是判断可变参数的个数来确定key的嵌套层数。再进行条件执行,等以后找到了统一的写法再进行修改。目前这样也能在工程当中使用。
源json文件:
{
"ID": 20,
"longitude": "112.12345",
"latitude": "28.67890",
"num": 123,
"openFlag": true,
"name": "xi xi",
"data": [
4,
2,
3,
4,
5
],
"color": {
"book": "red",
"clothes": "white",
"trousers": "black"
}
}
修改之后:
{
"ID": 60,
"longitude": "112.12345",
"latitude": "28.67890",
"num": 123,
"openFlag": false,
"name": "xi xi",
"data": [
4,
2,
3,
4,
5
],
"color": {
"book": "blue",
"clothes": "white",
"trousers": "black"
}
}
执行结果:
-2
-1
0
0
0
可以看出,ID、book和openFlag已经修改了。
接下来使用C++调用python代码,注意编译的时候需要连接python库,我这里使用的是2.7版本,所以是 -lpython2.7
#include "../common.h"
#include <jsoncpp/json/json.h>
#include <python2.7/Python.h>
int main()
{
Py_Initialize();
ifstream readFile("123.json",ios::binary);
if(!readFile.is_open())
{
printf("open fail\n");
return -1;
}
else
{
Json::Reader reader;
Json::Value root;
if(reader.parse(readFile,root)) //reader将文件中的内容解析到root
{
cout << root << endl; //结果的显示顺序和文件中并不一致
cout << "------------------------C++---------------------------" << endl;
//导入环境变量
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//导入模块
PyObject *pModule = PyImport_ImportModule("testJson");
if(pModule == NULL)
{
printf("NO testJson\n");
}
PyObject *pFunc = PyObject_GetAttrString(pModule, "updateJson");
if(pModule == NULL)
{
printf("NO updateJson\n");
}
PyObject *args = Py_BuildValue("(sis)","789.json",88,"ID");
/*这样也是可行的
PyObject *args = PyTuple_New(3);
PyTuple_SetItem(args, 0, Py_BuildValue("s","789.json");
PyTuple_SetItem(args, 1, Py_BuildValue("i",99));
PyTuple_SetItem(args, 2, Py_BuildValue("s","ID"));
*/
PyObject *retPython = PyEval_CallObject(pFunc,args); //调用python函数
int ret = -1;
PyArg_Parse(retPython, "i",&ret); //把返回值转为C++类型
printf("ret = %d\n",ret);
Py_DECREF(pModule);
Py_DECREF(pFunc);
Py_DECREF(args);
Py_DECREF(retPython);
}
else
{
cout << "no reader" << endl;
}
readFile.close();
//释放python,与Py_Initialize()对应
Py_Finalize();
return 0;
}
}
GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e
3 个月前
8c391e04
6 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)