说明
VS2017 + jsoncpp-00.11.z(目前最新版) + X64编译;
详细使用步骤,包括:下载编译Jsoncpp、VS2017功能设置、Jsoncpp使用举例;
Jsoncpp下载和编译
下载jsoncpp
https://github.com/open-source-parsers/jsoncpp/tree/master编译:
cd D:\work\program\open_source\jsoncpp-00.11.z\jsoncpp-00.11.z
//建一个编译工程目录,目录名随意
mkdir build_2
cd build_2
//使用cmake编译,
//我使用的VS2017自带的cmake.exe
//“..” 表示CMakeLists.txt在外面的目录
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ..
// 如果编译x64版本增加参数: -G "Visual Studio 15 2017 Win64"
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" .. -G "Visual Studio 15 2017 Win64"
打开build_2/jsoncpp.sln 进行编译即可;
一般而言,我们使用动态链接,(静态链接类似,不做介绍),那么需要如下几个目录:
-
头文件目录
-
编译生成的bin目录,里面存放了动态库
-
编译生成的lib目录,里面存放了链接库
VS2017使用Jsoncpp的工程设置
-
把jsoncpp的头文件、lib、dll拷过来:
PS:我是在工程中新建了jsoncpp-00.11.z\x64,然后拷贝过来;
-
设置lib库目录:
-
设置lib库名称:
-
设置头文件包含路径:
设置dll目录,我们把工作目录改为输出目录,并把dll到输出目录,避免手动拷贝dll:
-
链接结束时,拷贝dll到输出目录:
-
并把工作目录改为输出目录:
Jsoncpp的使用
如下代码,包含main()函数,可以直接拷贝运行;
Json写文件
#include
#include
#include
#include "json/json.h"
using namespace std;
int saveToFile(const string& file_name, const Json::Value& value)
{
ofstream ofs; //标准输出流
ofs.open(file_name); //创建文件
if (!ofs.is_open())
{
cout << "error, open file failed. \n";
return -1;
}
ofs << value.toStyledString(); //输出
ofs.close();
return 0;
}
int main(int argc, char** argv)
{
Json::Value value; //定义根节点
{
Json::Value jsonItem;
jsonItem["item1"] = "one";
jsonItem["item2"] = 2;
value.append(jsonItem);
jsonItem.clear();
jsonItem["item1.0"] = 1.0;
jsonItem["item2.0"] = 2.0;
value.append(jsonItem);
value.append("item3");
}
cout << "json data: \n" << value.toStyledString() << endl;
if (saveToFile("didi_test.json", value) != 0)
{
return -1;
}
cout << "save to file OK. \n";
return 0;
}
didi_test.json:
Jsoncpp支持注释
虽然json被强烈不建议添加注释,但是jsoncpp仍然支持注释,格式类似如下:didi_test_comments.json
// root info
[
{
"item1" : "one", /* item1 info */
"item2" : 2
},
{
"item1.0" : 1.0,
"item2.0" : 2.0
},
"item3"
]
如下代码,读取该文件;
#include
#include
#include
#include "json/json.h"
using namespace std;
int readFromFile(const Json::CharReaderBuilder& builder, const string& file_name, Json::Value& value)
{
ifstream ifs; //标准输入流
ifs.open(file_name);
if (!ifs.is_open())
{
cout << "error, open file failed. \n";
return -1;
}
JSONCPP_STRING errs;
if (!parseFromStream(builder, ifs, &value, &errs)) //从ifs中读取数据到jsonRoot
{
cout << "error, parseFromStream failed. \n";
return -1;
}
return 0;
}
int main(int argc, char** argv)
{
Json::Value value;
Json::CharReaderBuilder builder;
builder["collectComments"] = true;
builder["allowComments"] = true;
if (readFromFile(builder, "didi_test_comments.json", value) != 0)
{
return -1;
}
cout << "read from file with Comments:\n" << value.toStyledString() << endl;
return 0;
}
输出:
PS:读到的数据也是带注释的;后续写入文件也可以包含注释;
Jsoncpp的序列化和反序列化
Json序列化,即把Json数据转换成字符串,以便于发给其他进程或网络间进行数据通讯;
Jsoncpp序列化时,类似于大端,即高位在前,低位在后,十进制方式(而不是十六进制)从高位到低位取出每位的值,依次存放到字符串中:
比如:
参见Jsoncpp实现代码valueToString()方法:
enum {
/// Constant that specify the size of the buffer that must be passed to
/// uintToString.
uintToStringBufferSize = 3 * sizeof(uint64_t) + 1
};
// Defines a char buffer for use with uintToString().
typedef char UIntToStringBuffer[uintToStringBufferSize];
static inline void uintToString(uint64_t value, char*& current) {
*--current = 0;
do {
*--current = static_cast(value % 10U + static_cast('0'));
value /= 10;
} while (value != 0);
}
string valueToString(uint64_t value) {
UIntToStringBuffer buffer;
char* current = buffer + sizeof(buffer);
uintToString(value, current);
assert(current >= buffer);
return current;
}