JSONCpp

c++下面操作json的一个开源类库,比较好用,这里记录一下常用的操作。

github

编译方式更新了:
先使用 cmake . 编译一下,然后在执行 python

"D:\Program Files\CMake\bin\cmake.exe" .
python amalgamate.py

Generating amalgamated source and header
执行完毕后会在 dist 路径下面生成 jsoncpp.cpp 和 json 目录,里面有两个头文件
把生成的.cpp 和 .h 加入工程

添加 inlcude 路径

#include <json/json.h>

构建数组对象

// 对象数组
jsonArr["paid"] = it.paramNo;
jsonArr["name"] = it.paramName;
jsonArr["unit"] = it.unit;
jsonDev["param"].append(jsonArr);

// 字符串数据
value["andy"].append( "005" );
value["andy"].append( "123" );
value["andy"].append( "true" );

// 空数组
Json::Value root;
root["datas"].resize(0);

// 第二种方式
jsonRet["datas"] = Json::Value(Json::ValueType::arrayValue);

中文支持

Json 1.9.2
只需要在打开的时候设置一下默认的参数就可以了,读取的时候是 UTF8 的要转一下 GBK
这些写入文件就能正常看到中文了。

Json::StreamWriterBuilder wBuilder;
Json::Value def;
def["emitUTF8"] = true;
wBuilder.setDefaults(&def);
// json 版本 1.8.4
// 在src\lib_json\json_writer.cpp中 找到 valueToQuotedStringN函数,

// 将 default 改为下面的代码,直接返回字符
default:
result += *c;
break;

// .重新编译jsoncpp库,重新生成lib_json.lib

转为字符串

//数组类型 
Json::Value json = ...;
Json::StreamWriterBuilder builder;
builder["indentation"] = ""; // If you want whitespace-less output
const std::string output = Json::writeString(builder, json);

//数组类型
string output = val_array.toStyledString();

从字符串解析json

//parse response
Json::Value root;
Json::CharReaderBuilder reader;
Json::CharReader* pchReader = reader.newCharReader();
string strErr;
bool bRet = pchReader->parse(strRet.c_str(), strRet.c_str() + strRet.size(), &root, &strErr);
delete pchReader;
if (bRet == false)
{
string strMsg = "parse server response failed." + strRet;
LOG_ERROR(g_log,strMsg);
goto skip_return;
}

版本:1.8.4

Json::Reader reader;
Json::Value value;
if (reader.parse(json, value))
{
...
}

判断key是否存在

if (m_root.isMember(objName))
{
ret = m_root[objName].asInt64();;
}

删除对象元素

Json::Value jsonParam = map2jsonObj(mapOut);
jsonParam.removeMember("instId");

从文件读入

//配置文件,根据输入key获取数据
map<string, string> mapConf;
mapConf["dbIp"] = "";
mapConf["dbName"] = "";
mapConf["dbPwd"] = "";
mapConf["dbUser"] = "";
readJsonFromFile(m_configPath, mapConf);

int readJsonFromFile(wstring filePath, map<string,string>& out)
{
int iRet = 0;
Json::Reader reader;
Json::Value root;

//从文件中读取,保证当前文件有test.json文件
ifstream in(filePath, ios::binary);
if (!in.is_open())
{
iRet = -1;
}
else
{
if (reader.parse(in, root))
{
map<string, string>::iterator it;
for ( it = out.begin(); it != out.end(); ++it)
{
out[ it->first ] = root[ it->first ].asString();
}
}
else
{
iRet = -2;
}
}
in.close();
return 0;
}

输出到文件

int writeJsonToFile(Json::Value& root, wstring filePath)
{
//输出到文件
ofstream os;
os.open(filePath);

//缩进输出
Json::StreamWriterBuilder builder;
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
writer->write(root, &os);

os.close();
return 0;
}
// 格式化输出
Json::StreamWriterBuilder builder;
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
writer->write(root, &std::cout);

// 无格式输出
Json::StreamWriterBuilder builder;
builder.settings_["indentation"] = "";
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
writer->write(root, &std::cout);

删除数组元素

Json::Value root;
Json::Value delete;
root.removeIndex(num,&delete);

遍历数组

/*
{
"encoding" : "UTF-8",
"plug-ins" : [
"python",
"c++",
"ruby"
],
"indent" : { "length" : 3, "use_space": true }
}
*/
Json::Value val_array = rootParse["plug-ins"];
int i = 0;
for(auto it:val_array)
{
str = it.asString();
switch (i)
{
case 0:
ASSERT(str == "python");
break;
case 1:
ASSERT(str == "c++");
break;
case 2:
ASSERT(str == "ruby");
break;
default:
ASSERT(false);
}
}

//倒序处理
int cnt = jsonDatas.size();
for (int i = cnt - 1; i >= 0; --i )
{
...
}

遍历对象

/*
{"cmdType":14,"param":[{"2":[1,2,3]},{"3":[1,2,3]}]}
*/

Json::Value jsonParser = readJsonFromString(strRet);
Json::Value jsonArr = jsonParser["param"];
for (auto&it:jsonArr)
{
Json::Value::Members members;
members = it.getMemberNames(); // 获取所有key的值
for (Json::Value::Members::iterator iterMember = members.begin(); iterMember != members.end(); iterMember++) // 遍历每个key
{
std::string strKey = *iterMember;
if (it[strKey.c_str()].isString())
{
std::string strVal = it[strKey.c_str()].asString();
}
else if (it[strKey.c_str()].isInt())
{
int iVal = it[strKey.c_str()].asInt();
}
else if (it[strKey.c_str()].isDouble())
{
double dVal = it[strKey.c_str()].asDouble();
}
else
{
std::string strVal = it[strKey.c_str()].toStyledString();
}
}
}