JSON定义:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。它是基于 JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON采用完全独立于程序语言的文本格式,但是也使用了类C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
应用场景:
json本身只是一种数据存储格式,嵌在http协议报文进行网络数据交互是常见用法之一,在rpc调用中,如果涉及到json的传输,一般需要嵌套在其他协议中,以便于进行json边界处理,cjson和jsoncpp是常用的json解析库,其实cjson和jsoncpp本身不是做序列化和反序列化的工具库,只是一个json格式字符串的解析器,如果把json用于rpc的话,也还是需要第三方工具对json数据进行序列化。
1. Json 语法
JSON 语法是JavaScript 语法的子集。
比如下面就是一个json 对象,里面包含了字符串、整数、浮点数、普通数组、对象、
对象数组,从中可以窥探到json 的语法。
Key-value
{
"name": "milo",
"age": 80,
"professional": {
"english": 4,
"putonghua": 2,
"computer": 3,
},
"languages": ["C++", "C"],
"phone": {
"number": "18570368134",
"type": "home"
},
"books": [{
"name": "Linux kernel development",
"price": 7.7
}, {
"name": "Linux server development",
"price": 8.0
}],
"vip": true,
"address": null
}
数组的表示"languages": [“C++”, “C”],
数组,成员是对象
"books": [{
"name": "Linux kernel development",
"price": 7.7
}, {
"name": "Linux server development",
"price": 8.0
}],
1.1 JSON 语法规则
JSON 语法是JavaScript 对象表示语法的子集。
数据在名称/值对中
数据由逗号分隔
大括号保存对象
中括号保存数组
1.2 JSON 名称/值对
JSON 数据的书写格式是:名称/值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
“name” : “milo”
1.3 JSON 值
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或false)
数组(在中括号中)
对象(在大括号中)
null
1.3.1 JSON 数字
JSON 数字可以是整型或者浮点型:
{ “age”:30 }
1.3.2 JSON 对象
JSON 对象在大括号({})中书写:
对象可以包含多个名称/值对:
{ “name”:“Linux 服务器开发” , “url”:“www.0voice.com” }
1.3.3 JSON 数组
JSON 数组在中括号中书写:
数组可包含多个对象:
{
“sites”: [
{ “name”:“Linux 服务器开发” , “url”:“www.0voice.com” },
{ “name”:“google” , “url”:“www.google.com” },
{ “name”:“微博” , “url”:“www.weibo.com” }
]
}
在上面的例子中,对象"sites" 是包含三个对象的数组。每个对象代表一条关于某
个网站(name、url)的记录。
1.3.4 JSON 布尔值
JSON 布尔值可以是true 或者false:
{ “flag”:true }
1.3.5 JSON null
JSON 可以设置null 值:
{ “address”:null }
2. Jsoncpp
2.1 Jsoncpp 安装
jsoncpp 是一个c++封装的json 包,跨平台支持windows、linux、unix 等多系统。
jsoncpp 源码地址:https://github.com/open-source-parsers/jsoncpp
ubuntu 安装
sudo apt-get install libjsoncpp-dev
引用头文件
库的头文件安装在/usr/include/jsoncpp 中,
库API 文档默认在/usr/share/doc/libjsoncpp-dev/jsoncpp-api-html/目录下
#include <jsoncpp/json/json.h>
示例代码jsoncpp_test.c
#include <iostream>
#include <string>
#include "jsoncpp/json/json.h"
#include "jsoncpp/json/value.h"
#include "jsoncpp/json/writer.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
Json::Value root;
Json::FastWriter fast;
root["ModuleType"] = Json::Value(1);
root["MOduleCode"] = Json::Value("China");
cout<<fast.write(root)<<endl;
Json::Value sub;
sub["version"] = Json::Value("1.0");
sub["city"] = Json::Value(root);
fast.write(sub);
cout<<sub.toStyledString()<<endl;
return 0;
}
编译
g++ jsoncpp_test.c -o test -ljsoncpp
2.2 Jsoncpp 支持的值
jsoncpp 使用Json::Value 对象来保存JSON 串,Json::Value 对象可以表示如下数据类
型:
2.3 读取数据
在知道如何描述JSON 串后,我们来看下Json::Value 类提供了哪些方法来访问保存
的数据:
2.3.1 检测保存的数据类型
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
2.3.2 基础数据类型的访问
const char* asCString() const;
JSONCPP_STRING asString() const;
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
2.3.3 数组风格
// ValueType::arrayValue 和ValueType::objectValue 数据类型的访问,操作方式很类似
C++的vector,可以使用数组风格或者迭代器风格来操作数据
root["name"] = "milo";
ArrayIndex size() const;
Value& operator[](ArrayIndex index);
Value& operator[](int index);
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
Value get(ArrayIndex index, const Value& defaultValue) const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
// ValueType::objectValue 数据类型的访问,操作方式很类似C++的map
Value& operator[](const char* key);
const Value& operator[](const char* key) const;
Value& operator[](const JSONCPP_STRING& key);
const Value& operator[](const JSONCPP_STRING& key) const;
Value& operator[](const StaticString& key);
Value& operator[](const CppTL::ConstString& key);
const Value& operator[](const CppTL::ConstString& key) const;
Value get(const char* key, const Value& defaultValue) const;
Value get(const char* begin, const char* end, const Value& defaultValue) const;
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
2.4 修改数据
知道如何获取Json::Value 对象或其子对象后,我们来看下如何修改Json::Value 保存
的数据:
// 直接使用=赋值就可以了
Value& operator=(Value other);
// 因为Json::Value 已经实现了各种数据类型的构造函数
Value(ValueType type = nullValue);
Value(Int value);
Value(UInt value);
Value(Int64 value);
Value(UInt64 value);
Value(double value);
Value(const char* value);
Value(const char* begin, const char* end);
Value(const StaticString& value);
Value(const JSONCPP_STRING& value);
Value(const CppTL::ConstString& value);
Value(bool value);
Value(const Value& other);
Value(Value&& other);
2.5 注意事项
(1)对于Int、Uint、Int64、UInt64 等类型,注意类型。
root[“age”] = 80; 默认为Int 类型
可以类似root[“age”] = (Json::Uint)80; 强制转换类型
(2)如果要将变量设置为null,则使用
root[“address”] = Json::nullValue; // 不要用NULL
2.6 使用范例
见代码
3. cJSON
3.1 cJSON 编译安装
github 地址:https://github.com/DaveGamble/cJSON
下载
git clone https://github.com/DaveGamble/cJSON.git
参考Readme 进行编译
可以直接使用cJSON.h 和cJSON.c 加入到源文件。
3.2 数据结构定义
3.2.1 cJSON 结构
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use Get
ArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain o
f the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* The item's number, if type==cJSON_Number */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list
of subitems of an object. */
char *string;
} cJSON;
next、prev 用于遍历数组或对象链的前向后向链表指针;child 指向数组或对象的孩子
节点;type 是value 的类型;valuestring 是字符串值;valueint 是整数值;valuedouble
是浮点数值;string 是key 的名字。
3.2.2 cJSON 支持的类型
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
valuestring,当类型为cJSON_String 或cJSON_Raw 时,value 的值,type 不符时
为NULL
valueint,当类型为cJSON_Number 时,value 的值
valuedouble,当类型为cJSON_NUmber 时,value 的值(主要用这个)
string, 代表key,value 键值对中key 的值
3.3 重点函数
3.3.1 cJSON_Parse
/* Supply a block of JSON, and this returns a cJSON object
you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
//作用:将一个JSON 字符串,按照cJSON 结构体的结构序列化整个数据包,并在堆中开辟一块内
//存存储cJSON 结构体。
//返回值:成功返回一个指向内存块中的cJSON 的指针,失败返回NULL。
3.3.2 cJSON_Delete
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
//作用:释放位于堆中cJSON 结构体内存。
//返回值:无
//注意:在使用cJSON_Parse()获取cJSON 指针后,若不再使用了,则需要调用cJSON_Delete()
//对其释放,否则会导致内存泄漏。
3.3.3 cJSON_Print
/* Render a cJSON entity to text for transfer/storage.
Free the char* when finished. */
extern char *cJSON_Print(const cJSON *item);
//作用:将cJSON 数据解析成JSON 字符串,并在堆中开辟一块char*的内存空间存储JSON 字符
//串。cJSON_PrintUnformatted()与cJSON_Print()类似,只是打印输出不带格式,而只是一个
//字符串数据。
//返回值:成功返回一个char*指针该指针指向位于堆中JSON 字符串,失败返回NULL。
//注意:通过cJSON_Print()可以将cJSON 链表中所有的cJSON 对象打印出来,但是需要手动去
//释放对应的资源:free(char *)。
3.3.4 cJSON_Version
/* returns the version of cJSON as a string */
extern const char* cJSON_Version(void);
//作用:获取当前使用的cJSON 库的版本号。
//返回值:返回一个字符串数据。
3.3.5 cJSON_GetArrayItem
/* Retrieve item number "item" from array "array".
Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(const cJSON *array, int item);
//作用:从object 的cJSON 链中寻找key 为string 的cJSON 对象。
//返回值:成功返回一个指向cJSON 类型的结构体指针,失败返回NULL。
//与cJSON_GetObjectItem()类似的接口还有:
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(const cJSON *array);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string)
;
extern int cJSON_HasObjectItem(const cJSON *object, const char *string);
3.4 所有函数简介
3.5 使用范例
下面的例子是将json嵌在http中,服务端将http报文解析出对应的json字段:
注释:收发双方按照约定的json格式(json字段)进行解析
//解析用户登陆信息的json包login_buf
//用户名保存在username,密码保存在pwd
int get_login_info(char *login_buf, char *username, char *pwd)
{
int ret = 0;
//解析json包
//解析一个json字符串为cJSON对象
cJSON * root = cJSON_Parse(login_buf);
if(NULL == root)
{
LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_Parse err\n");
ret = -1;
goto END;
}
//返回指定字符串对应的json对象
//用户
cJSON *child1 = cJSON_GetObjectItem(root, "user");
if(NULL == child1)
{
LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_GetObjectItem err\n");
ret = -1;
goto END;
}
//LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
strcpy(username, child1->valuestring); //拷贝内容
//密码
cJSON *child2 = cJSON_GetObjectItem(root, "pwd");
if(NULL == child2)
{
LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_GetObjectItem err\n");
ret = -1;
goto END;
}
//LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
strcpy(pwd, child2->valuestring); //拷贝内容
END:
if(root != NULL)
{
cJSON_Delete(root);//删除json对象
root = NULL;
}
return ret;
}
cjson使用案例:
/*
* @Descripttion: cjson测试
* @version: 1.0
* @Author: Darren
* @Date: 2019-10-29 10:14:51
* @LastEditors: Please set LastEditors
* @LastEditTime: 2020-06-09 20:28:49
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "cJSON.h"
static uint64_t getNowTime()
{
struct timeval tval;
uint64_t nowTime;
gettimeofday(&tval, NULL);
nowTime = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
return nowTime;
}
char *CJsonEncode()
{
// 创建json对象
cJSON *root = cJSON_CreateObject();
// 添加键值对
cJSON_AddItemToObject(root, "name", cJSON_CreateString("darren"));
cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(80));
// 创建json数组
cJSON *languages = cJSON_CreateArray();
cJSON_AddItemToArray(languages, cJSON_CreateString("C++"));
cJSON_AddItemToArray(languages, cJSON_CreateString("Java"));
cJSON_AddItemToObject(root, "languages", languages);
cJSON *phone = cJSON_CreateObject();
cJSON_AddItemToObject(phone, "number", cJSON_CreateString("18570368134"));
cJSON_AddItemToObject(phone, "type", cJSON_CreateString("home"));
cJSON_AddItemToObject(root, "phone", phone);
cJSON *book0 = cJSON_CreateObject();
cJSON_AddItemToObject(book0, "name", cJSON_CreateString("Linux kernel development"));
cJSON_AddItemToObject(book0, "price", cJSON_CreateNumber(7.7));
cJSON *book1 = cJSON_CreateObject();
cJSON_AddItemToObject(book1, "name", cJSON_CreateString("Linux server development"));
cJSON_AddItemToObject(book1, "price", cJSON_CreateNumber(8.0));
// 创建json数组
cJSON *books = cJSON_CreateArray();
cJSON_AddItemToArray(books, book0);
cJSON_AddItemToArray(books, book1);
cJSON_AddItemToObject(root, "books", books);
cJSON_AddItemToObject(root, "vip", cJSON_CreateBool(1));
cJSON_AddItemToObject(root, "address", cJSON_CreateString("yageguoji")); // NULL值的问题
// 格式化json对象
char *text = cJSON_Print(root);
// size_t len = strlen(text) + 1;
// char *strJson = malloc(len);
// memcpy(strJson, text, len);
// printf("text:%s\n", text);
// FILE* fp = fopen("root.json", "w");
// fwrite(text, 1, strlen(text), fp);
// fclose(fp);
cJSON_Delete(root);
return text;
}
void printCJson(cJSON *root)
{
cJSON *name = cJSON_GetObjectItem(root, "name");
cJSON *age = cJSON_GetObjectItem(root, "age");
cJSON *languages = cJSON_GetObjectItem(root, "languages");
cJSON *phone = cJSON_GetObjectItem(root, "phone");
cJSON *books = cJSON_GetObjectItem(root, "books");
cJSON *vip = cJSON_GetObjectItem(root, "vip");
cJSON *address = cJSON_GetObjectItem(root, "address");
printf("name: %s\n", name->valuestring);
printf("age: %d\n", age->valueint);
printf("languages: ");
for (int i = 0; i < cJSON_GetArraySize(languages); i++)
{
cJSON *lang = cJSON_GetArrayItem(languages, i);
if (i != 0)
{
printf(", ");
}
printf("%s", lang->valuestring);
}
printf("\n");
cJSON *number = cJSON_GetObjectItem(phone, "number");
cJSON *type = cJSON_GetObjectItem(phone, "type");
printf("phone number: %s, type: %s\n", number->valuestring, type->valuestring);
for (int i = 0; i < cJSON_GetArraySize(books); i++)
{
cJSON *book = cJSON_GetArrayItem(books, i);
cJSON *name = cJSON_GetObjectItem(book, "name");
cJSON *price = cJSON_GetObjectItem(book, "price");
printf("book name: %s, price: %lf\n", name->valuestring, price->valuedouble);
}
printf("vip: %d\n", vip->valueint);
if (address && !cJSON_IsNull(address))
{
printf("address: %s\n", address->valuestring);
}
else
{
printf("address is null\n");
}
}
int CJsonDecode(const char *strJson)
{
if (!strJson)
{
printf("strJson is null\n");
return -1;
}
cJSON *root = cJSON_Parse(strJson);
// printCJson(root);
cJSON_Delete(root);
return 0;
}
#define TEST_COUNT 100000
int main(void)
{
char *strJson = NULL;
strJson = CJsonEncode();
printf("strJson size:%lu, string:%s\n", strlen(strJson), strJson);
CJsonDecode(strJson);
free(strJson);
#if 0
uint64_t startTime;
uint64_t nowTime;
startTime = getNowTime();
printf("cjson encode time testing\n");
for (int i = 0; i < TEST_COUNT; i++)
{
strJson = CJsonEncode();
if (strJson)
{
free(strJson);
strJson = NULL;
}
}
nowTime = getNowTime();
printf("cjson encode %u time, need time: %lums\n", TEST_COUNT, nowTime - startTime);
strJson = CJsonEncode();
startTime = getNowTime();
printf("\ncjson decode time testing\n");
for (int i = 0; i < TEST_COUNT; i++)
{
CJsonDecode(strJson);
}
nowTime = getNowTime();
printf("cjson decode %u time, need time: %lums\n", TEST_COUNT, nowTime - startTime);
free(strJson);
#endif
return 0;
}
jsoncpp使用案例:
/*
* @Descripttion: 测试jsoncpp的使用方法和性能
* @version: 1.0
* @Author: Darren
* @Date: 2019-10-27 20:49:58
* @LastEditors: Darren
* @LastEditTime: 2019-10-30 14:44:48
*/
#include <iostream>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <json/json.h>
/*
{
"name": "darren",
"age": 80,
"languages": ["C++", "C"],
"phone": {
"number": "18570368134",
"type": "home"
},
"books":[
{
"name": "Linux kernel development",
"price":7.7
},
{
"name": "Linux server development",
"price": 8.0
}
],
"vip":true,
"address": null
}
*/
static uint64_t getNowTime()
{
struct timeval tval;
uint64_t nowTime;
gettimeofday(&tval, NULL);
nowTime = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
return nowTime;
}
std::string JsoncppEncodeNew()
{
std::string jsonStr;
// 一个value是可以包含多个键值对
Json::Value root, languages, phone, book, books;
// 姓名
root["name"] = "darren";
// 年龄
root["age"] = 80;
// 语言
languages[0] = "C++";
languages[1] = "Java";
root["languages"] = languages;
// 电话
phone["number"] = "18570368134";
phone["type"] = "home";
root["phone"] = phone;
// 书籍
book["name"] = "Linux kernel development";
book["price"] = 7.7;
books[0] = book; // 深拷贝
book["name"] = "Linux server development";
book["price"] = 8.0;
books[1] = book; // 深拷贝
root["books"] = books;
// 是否为vip
root["vip"] = true;
// address信息空null
root["address"] = "yageguoji";
Json::StreamWriterBuilder writerBuilder;
std::ostringstream os;
std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
jsonWriter->write(root, &os);
jsonStr = os.str();
// std::cout << "Json:\n" << jsonStr << std::endl;
return jsonStr;
}
std::string JsoncppEncodeOld()
{
std::string jsonStr;
Json::Value root, languages, phone, book, books;
// 姓名
root["name"] = "darren";
//root["name"] = Json::nullValue;
// 年龄
root["age"] = 80;
// 语言
languages[0] = "C++";
languages[1] = "Java";
root["languages"] = languages;
// 电话
phone["number"] = "18570368134";
phone["type"] = "home";
root["phone"] = phone;
// 书籍
book["name"] = "Linux kernel development";
book["price"] = (float)7.7;
books[0] = book;
book["name"] = "Linux server development";
book["price"] = (float)8.0;
books[1] = book;
root["books"] = books;
// 是否为vip
root["vip"] = true;
// address信息空null
root["address"] = "yageguoji"; //;// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL
Json::FastWriter writer;
jsonStr = writer.write(root);
// std::cout << "Json:\n" << jsonStr << std::endl;
return jsonStr;
}
// 不能返回引用
Json::Value JsoncppEncodeOldGet()
{
Json::Value root;
Json::Value languages, phone, book, books;
// 姓名
root["name"] = "darren";
//root["name"] = Json::nullValue;
// 年龄
root["age"] = 80;
// 语言
languages[0] = "C++";
languages[1] = "Java";
root["languages"] = languages;
// 电话
phone["number"] = "18570368134";
phone["type"] = "home";
root["phone"] = phone;
// 书籍
book["name"] = "Linux kernel development";
book["price"] = (float)7.7;
books[0] = book;
book["name"] = "Linux server development";
book["price"] = (float)8.0;
books[1] = book;
root["books"] = books;
// 是否为vip
root["vip"] = true;
// address信息空null
root["address"] = Json::nullValue; //"yageguoji";// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL
std::cout << "JsoncppEncodeOldGet:\n" << std::endl;
return root;
}
void printJsoncpp(Json::Value &root)
{
if(root["name"].isNull())
{
std::cout << "name null\n";
}
std::cout << "name: " << root["name"].asString() << std::endl;
std::cout << "age: " << root["age"].asInt() << std::endl;
Json::Value &languages = root["languages"];
std::cout << "languages: ";
for (uint32_t i = 0; i < languages.size(); ++i)
{
if (i != 0)
{
std::cout << ", ";
}
std::cout << languages[i].asString();
}
std::cout << std::endl;
Json::Value &phone = root["phone"];
std::cout << "phone number: " << phone["number"].asString() << ", type: " << phone["type"].asString() << std::endl;
Json::Value &books = root["books"];
for (uint32_t i = 0; i < books.size(); ++i)
{
Json::Value &book = books[i];
std::cout << "book name: " << book["name"].asString() << ", price: " << book["price"].asFloat() << std::endl;
}
std::cout << "vip: " << root["vip"].asBool() << std::endl;
if (!root["address"].isNull())
{
std::cout << "address: " << root["address"].asString() << std::endl;
}
else
{
std::cout << "address is null" << std::endl;
}
}
bool JsoncppDecodeNew(const std::string &info)
{
if (info.empty())
return false;
bool res;
JSONCPP_STRING errs;
Json::Value root;
Json::CharReaderBuilder readerBuilder;
std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
res = jsonReader->parse(info.c_str(), info.c_str() + info.length(), &root, &errs);
if (!res || !errs.empty())
{
std::cout << "parseJson err. " << errs << std::endl;
return false;
}
// printJsoncpp(root);
return true;
}
bool JsoncppDecodeOld(const std::string &strJson)
{
if (strJson.empty())
return false;
bool res;
Json::Value root;
Json::Reader jsonReader;
res = jsonReader.parse(strJson, root);
if (!res)
{
std::cout << "jsonReader.parse err. " << std::endl;
return false;
}
// printJsoncpp(root);
return true;
}
const char *strCjson = "{ \
\"name\": \"darren\", \
\"age\": 80, \
\"languages\": [\"C++\", \"C\"],\
\"phone\": { \
\"number\": \"18570368134\", \
\"type\": \"home\" \
}, \
\"books\": [{ \
\"name\": \"Linux kernel development\", \
\"price\": 7.700000 \
}, { \
\"name\": \"Linux server development\", \
\"price\": 8 \
}], \
\"vip\": true, \
\"address\": null \
} \
";
#define TEST_COUNT 100000
int main()
{
std::string jsonStrNew;
std::string jsonStrOld;
jsonStrNew = JsoncppEncodeNew();
// JsoncppEncodeNew size: 337
std::cout << "JsoncppEncodeNew size: " << jsonStrNew.size() << std::endl;
std::cout << "JsoncppEncodeNew string: " << jsonStrNew << std::endl;
JsoncppDecodeNew(jsonStrNew);
jsonStrOld = JsoncppEncodeOld();
// JsoncppEncodeOld size: 248
std::cout << "\n\nJsoncppEncodeOld size: " << jsonStrOld.size() << std::endl;
std::cout << "JsoncppEncodeOld string: " << jsonStrOld << std::endl;
JsoncppDecodeOld(jsonStrOld);
Json::Value root = JsoncppEncodeOldGet();
Json::FastWriter writer;
std::cout << "writer:\n" << std::endl;
std::string jsonStr = writer.write(root);
std::cout << "\n\njsonStr string: " << jsonStrOld << std::endl;
#if 1
uint64_t startTime;
uint64_t nowTime;
startTime = getNowTime();
std::cout << "jsoncpp encode time testing" << std::endl;
for(int i = 0; i < TEST_COUNT; i++)
{
JsoncppEncodeNew();
}
nowTime = getNowTime();
std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: "
<< nowTime-startTime << "ms" << std::endl;
startTime = getNowTime();
std::cout << "\njsoncpp encode time testing" << std::endl;
for(int i = 0; i < TEST_COUNT; i++)
{
JsoncppEncodeOld();
}
nowTime = getNowTime();
std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: "
<< nowTime-startTime << "ms" << std::endl;
startTime = getNowTime();
std::cout << "\njsoncpp decode time testing" << std::endl;
for(int i = 0; i < TEST_COUNT; i++)
{
JsoncppDecodeNew(jsonStrNew);
}
nowTime = getNowTime();
std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: "
<< nowTime-startTime << "ms" << std::endl;
startTime = getNowTime();
std::cout << "\njsoncpp decode time testing" << std::endl;
for(int i = 0; i < TEST_COUNT; i++)
{
JsoncppDecodeOld(jsonStrNew);
}
nowTime = getNowTime();
std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: "
<< nowTime-startTime << "ms" << std::endl;
#endif
return 0;
}
RapidJSON也是json生成器和解析器之一,这里就不过多介绍了,具体可以参考:
https://blog.csdn.net/fengbingchun/article/details/91139889