原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://tsiannian.blog.51cto.com/3540488/730879
基本概念:
Object:它实际上是一个键:值对,在不同的语言中有不同的名称。
写成文本如下:{"name":"Tsiannian","age":"23","available":"true"……}
string: 就是字符串嘛,这里是作为key。
value:他是各种不同的类型的一个统称,作为值 。
值可以是object 和 array 这就是json 嵌套的基础。
array:被称为数组,它由多个值来构成,
写成文本就是:["boy","girl",……]。
使用示例:
json读取:
-
-
- #include "stdafx.h"
- #include <iostream>
- #include <fstream>
- #include "json/json.h"
-
- using namespace std;
- int _tmain(int argc, char* argv[])
- {
- fstream file("test.json");
- if (!file)
- {
- cout<<"Open file test.json fail!!!"<<endl;
- getchar();
- return -1;
- }
- Json::Value root;
- Json::Reader reader;
- Json::FastWriter fast_writer;
-
- if (!reader.parse(file, root, false))
- {
- cout<<"Parse error"<<endl;
- getchar();
- return -1;
- }
- int size = root.size();
- for (int i = 0; i < size; ++i)
- {
- string name = root[i]["name"].asString();
- int age = root[i]["age"].asInt();
- cout<<"age:"<<age<<"\tname:"<<name<<endl;
- }
- getchar();
- return 0;
- }
这部分代码来自hackmind的博客,稍微修改了一点。
test.json内容为:[{"name" : "xiaoy", "age" :17} , {"name" : "xiaot", "age" : 20}……]
输出为:
json写入:
- #include "stdafx.h"
- #include <iostream>
- #include <fstream>
- #include "json/json.h"
-
- #define SIZE 10;
-
- using namespace std;
-
- int _tmain(int argc, char* argv[])
- {
-
- Json::Value root;
- Json::FastWriter fast_writer;
-
- Json::Value Person;
-
- Person["name"] = "Tsiannian";
- Person["age"] = "23";
- root.append(Person);
-
- Person["name"] = "zSai";
- Person["age"] = "21";
- root.append(Person);
-
- std::cout << fast_writer.write(root) << endl;
- getchar();
- return 0;
- }
输出内容为:
下面记录下Jsoncpp的设置:
- 下载Jsoncpp源码之后解压,在makefiles文件夹中有一个vs工程,注意编译成静态链接库。在Build目下会生成一个lib文件。
- 拷贝该lib文件到项目的目录,拷贝include下面的json目录到项目目录。
- 在项目目录中添加现有项,添加json目录下的头文件和lib静态库。
- 最重要的是:设置项目的运行时库为静态库。
son大家都耳熟能详了吧?现在Json广泛用于各类通信,特别是基于Http协议的通信,一般的服务端动态脚本语言都有库支持Json的编码与 解码。但很少有听过Json被C++使用来作为通信的格式,不过去了http://www.json.org/上面看 了,已经有很多C++的库来支持Json的编码和解码,因为一个小东西要用到,最后使用的是Jsoncpp这个库。
看到Jsoncpp的主页上介绍说,Jsoncpp是Json数据格式的编码解码器,提供reader和writer来进行解码和编码。下面就简要 的介绍Jsoncpp里头的玩意:
1.Reader
该库中的Reader类用来将字串或者流载入解析器。是的后期可以用Reader里面的解析方法来解码Json字串为C++认识的数据。可以用 Json::Reader来声明一个Reader实例。Reader中最常用的就是一个parse方法,该方法用来将载入的json字串解析为C++格式 的数据。
2.Value
这是该库中的核心类,用于存储各样格式的数据,可以包括int,double,short,char *,string,bool,object,array等几乎所有格式的数据。该库的编码和解码的核心功能都是用Value类实现的。就用以上的 Reader的parse方法来说,需要传入一个Value类别的引用值,就是用来存储Json数据的根值,并且可以用这个根值来存取其他的所有值。
3.Writer
这是该库的一个虚类,没有真正的实现encode的功能。需要重载里头的方法来实现真正的encode功能
4.FastWriter
这是该库中真正实现encode功能的类,用来实现将Value编码称为Json串.
我暂时用到的是以上的这些类,该库还提供处理Json字串的注释,提供style来格式化Json字串是的更容易人阅读等功能,这些都没有用到,等 以后用到了再来分享。下面用一段简短的代码来看以上这些Jsoncpp的基本功能:
C++语言:
01
/*
02
this function to encode game/play message
03
!IN
04
token:token string
05
game_id:game id
06
piece_array:piece array
07
08
!OUT
09
encoded json string of game/play message
10
11
!example:
12
token = “asdfasdf”
13
game_id=1;
14
piece_array = [{'A',true,0,1},{'A',true,1,2},{'A',true,2,3},{'A',true,3,4}]
15
16
return:
17
[{"game_id":1,"piece_array":[{"letter":65,"wild":true,"x":0,"y":1},{"letter":65,
18
"wild":true,"x":1,"y":2},{"letter":65,"wild":true,"x":2,"y":3},{"letter":65,"wil
19
d":true,"x":3,"y":4},{"letter":65,"wild":true,"x":4,"y":5}],”token”:”asdfasdf”}]
20
*/
21
string
encode_game_play_msg(
string
token
,
int
game_id
,
vector
<
piece
>
piece_array
){
22
Json
::
Value
root;
23
Json
::
Value
var;
24
25
//apply “token” and “game_id” value to json struct
26
var
[
"token"
]
=
token;
27
var
[
"game_id"
]
=
game_id;
28
29
Json
::
Value
pieces;
//store all pieces
30
for (
int
i
=
0;
i
<
piece_array
.
size();
i
++)
31
{
32
Json
::
Value
piece_ex;
//here it store just one piece
33
34
//next 4 lines to apply piece value to json struct
35
piece_ex
[
"letter"
]
=
piece_array
[
i
].
letter;
36
piece_ex
[
"wild"
]
=
piece_array
[
i
].
wild;
37
piece_ex
[
"x"
]
=
piece_array
[
i
].
x;
38
piece_ex
[
"y"
]
=
piece_array
[
i
].
y;
39
pieces
.
append(
piece_ex);
//ok,yes we just have apply One piece ,then push back to the array
40
}
41
var
[
"piece_array"
]
=
pieces;
//yes,store pieces in var [Value]
42
root
.
append(
var);
43
44
Json
::
FastWriter
writer;
45
return
writer
.
write(
var);
//generate json string:),here all is done
46
}
上面这段代码还是相对用到了jsoncpp的大部分编码功能的,用来将数据编码称为json字符串,下面会仔细的分析这段代码
1.首先请看注释中的!IN部分,这是这个函数的传入参数。有三个一个是string类型的token,一个是int类型的game_id,一个是 array,用来存储所有的piece。看!OUT部分就是所要输出的json格式的字符串。用后面的输出可以看到,这个Json字符串中有一个大的根 object,里头有三样东西,1.token,2.game_id,3.piece_array。
2.encode过程
首先之前已经说过,Value在Jsoncpp中是核心类,Reader和Writer都是用Value的功能。以上代码中有[]操作符来赋值给 Value,Value应该是类似一个map结构的数据仓库,用来用树存储所有的数据,最后转换后来编码称为Json格式的字符串。在编码数组的过程中 Value提供了一个append函数用来附加到Value里面,千万记得我前面说过,Value可以直接存数组。当然,Value的[]操作符不能直接 的用数组作为参数,如果能这样就牛了。C++这等编译语言是做不到这么动态的,所以可以看到代码里面其实是Value的嵌套,用Value来实现一个数组 元素的赋值,因为数组元素不是一个简单的编译器支持的内部类型,所以需要解开来赋值。
3.encode
最后直接用FastWriter来实现编码输出,这样一个典型的Jsoncpp的编码Json的过程。
再来看一段解码json串的代码
C++语言:
01
/*
02
this function decode lobby/data return message
03
!example
04
lobby data json string:
05
{\”game\”:{\
06
\”id\”:1,\
07
\”creator_id\”:2,\
08
\”user_max\”:500,\
09
\”template\”:{\”id\”:1},\
10
\”user_array\”:[\
11
{\"id\":1,\"name\":\"test1\"},\
12
{\"id\":2,\"name\":\"test2\"},\
13
{\"id\":3,\"name\":\"test3\"},\
14
{\"id\":4,\"name\":\"test4\"},\
15
{\"id\":5,\"name\":\"test5\"},\
16
{\"id\":6,\"name\":\"test6\"},\
17
{\"id\":7,\"name\":\"test7\"},\
18
{\"id\":8,\"name\":\"test8\"},\
19
{\"id\":9,\"name\":\"test9\"}\
20
]\
21
}}
22
this function will return a [game_info] structure to be filled by parsed result
23
game_info gi;
24
gi.id -> 1
25
gi.creator_id -> 2
26
gi.user_max -> 500
27
gi.template_r.id -> 1
28
gi.user_array -> [{1,"test1"},{2,"test2"}...] //this is a user_info array to store the game’s users
29
*/
30
game_info
decode_lobby_data_return_msg(
string
lobby_data_return_msg
){
31
Json
::
Value
root;
32
Json
::
Reader
reader;
33
game_info
gi;
34
bool
parsedOk
=
false;
35
parsedOk
=
reader
.
parse(
lobby_data_return_msg
,
root
,
false);
//decoding…
36
if (
!
parsedOk)
//decoded failed
37
{
38
cout
<<
“parsed error!
\n
“
<<
reader
.
getFormatedErrorMessages()
<<
endl;
39
gi
.
id
=
-
1000;
//game id = -1000,means parsed error!
40
return
gi;
41
}
42
43
Json
::
Value
game
=
root
[
"game"
];
44
/*
45
here three lines are to get value directly by json struct.
46
Json::Value has operator “[]” to get values by key directly,
47
if you want to know more about jsoncpp function,please view document i have send to you
48
*/
49
gi
.
id
=
game
[
"id"
].
asInt();
50
gi
.
creator_id
=
game
[
"creator_id"
].
asInt();
51
gi
.
user_max
=
game
[
"user_max"
].
asInt();
52
53
Json
::
Value
template_r
=
game
[
"template"
];
54
gi
.
template_r
.
id
=
template_r
[
"id"
].
asInt();
55
56
Json
::
Value
users
=
game
[
"user_array"
];
//because user_array is a array ,so we must get its element by [for] circle,please see [for] circle below
57
for (
int
index
=
0;
index
<
users
.
size();
index
++)
58
{
59
/*
60
in [for] circle,we must get user_info one by one,and fill in its value by values from json struct,
61
at last,push back into user_array to store the current user_info,then do again
62
*/
63
user_info
u;
64
u
.
id
=
users
[
index
][
"id"
].
asInt();
65
u
.
name
=
users
[
index
][
"name"
].
asString();
66
gi
.
user_array
.
push_back(
u);
67
}
68
69
return
gi;
70
}
这是一段典型的解码json字符串的代码,注释中已经非常明白的写出了该函数的输入和输出,下面简要的分析一下这段代码
1.parse,这个函数在上面的介绍中已经写过,是用来解码字串称为Value格式的数据的函数,然后是要判断函数的返回值,如果返回为 false,那么说明json字串解码错误。
2.当解码成功以后,就是要操作返回的Value值。这里对于如何取Value里头的值,Jsoncpp的Value类提供了两个方法,一个是 get函数,第二个是[]操作符,我个人觉得还是[]好用,传入的参数的json里头的key,你就可以把key所对应的value取出来
3.当提取出来的是数组时,需要逐个提取里面的元素,然后再用Value的转换功能来实现值的提取。Value提供asXXX函数来转换值。
以上的是简要的介绍了Jsoncpp里头的编码和解码功能。
本文出自 “Tsiannian爱学习” 博客,请务必保留此出处http://tsiannian.blog.51cto.com/3540488/730879