引用www.json.org上的對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就是一種基于Javascript的輕量級數據交換格式。它給我的感覺有點類似于xml,但寫法更隨意,并且用途不同。
這篇文章不會介紹JSON本身,因此,如果您首次接觸JSON,請務必先到http://www.json.org/去看完introduction.(這里還有中文版:http://www.json.org/json-zh.html)。
其實操作JSON數據比較方便的還是C#和Java,語句編寫也比較簡單、方便。C++操作JSON數據相對就要復雜一些,但只要理解了JSON這種數據格式,除了代碼字符量大一些以外,操作起來也不是很復雜。
在JSON官網上已經推薦了一些使用C++操作JSON的open source項目,我試用了幾種,最后選擇了TinyJSON。因為它只需要一個.hpp文件,看起來比較輕量級。但無論是哪種,多數C++操作JSON的項目,都需要使用boost,所以,在正式使用TinyJSON之前,你還需要把boost編譯并配置好。我使用的是boost 1.39.0。關于boost的編譯和配置,網上已經有很多介紹的文章了,這里就不再說。
說了一些廢話,下面言歸正傳,來看一下如何使用TinyJSON。
先從簡單的來,比如我們有這樣一段JSON數據:
{ "login_time": 1246068720 }
一目了然,名稱是login_time,值是1246068720。用TinyJSON讀取,代碼就可以這么寫:
1
string strJson = "{ \"login_time\": 1246068720 }";
2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());
3
if(var->type() == typeid(grammar<char>::object))
4

{
5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);
6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)
7
{
8
std::string strName = (*it).first;//這里你可以讀到名稱“login_time”
9
10
if((*it).second->type() == typeid(int))
11
{
12
int nValue = boost::any_cast<int>(*(*it).second);//這里將login_time的值讀到一個整型變量里。
13
}
14
}
15
}
(注,需要事前定義命名空間:using namespace json;,否則你需要寫成這樣:json::grammer<char>什么什么)JSON數據基本上都是“名稱-值”這樣的格式,其中“值”有很多類型,比如上面的例子是一個整型,還有字符類型、double、布爾等等。并且“值”不限于這些,還可以是一個數組,甚至又是一段JSON數據。
下面舉個“值”是數組的例子,比如這樣的一段JSON數據:
{ "auto_harvest": [26,28,25] }相應的讀取代碼如下:
1
string strJson = "{ \"auto_harvest\": [26,28,25] }";
2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());
3
if(var->type() == typeid(grammar<char>::object))
4

{
5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);
6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)
7
{
8
std::string strName = (*it).first; //這里讀到名稱“auto_harvest”
9
10
if((*it).second->type() == typeid(grammar<char>::array))
11
{
12
//這是一個數組類型,下面循環解析里面所有的元素
13
grammar<char>::array const & a = boost::any_cast<grammar<char>::array>(*(*it).second);
14
for(grammar<char>::array::const_iterator ita = a.begin(); ita != a.end(); ++ita)
15
{
16
if((*ita)->type() == typeid(int))
17
{
18
nValue = boost::any_cast<int>(*(*ita)); //這里會讀到每一個數組元素
19
}
20
}
21
}
22
}
23
}
再來一段“值”是另外一段JSON的例子,比如你拿到的JSON數據是這樣的:
{ "server_now": 1246117129.8, "return_code": 0, "params": {"rekoo_killer": "123456"} }
我們可以將上面的JSON數據分為“兩級”,如下:
server_now : 1246117129.8 (第一級)
return_code : 0 (第一級)
param : (第一級)
rekoo_killer : 123456 (第二級)
其中
rekoo_killer : 123456是param的“值”,而
rekoo_killer : 123456本身又可以單獨看做一段獨立的JSON數據,它在TinyJSON中被作為一個object類型。
用TinyJSON解析上面的JSON數據,代碼可以這樣寫:
1
string strJson = "{ \"server_now\": 1246117129.8, \"return_code\": 0, \"params\": {\"rekoo_killer\": \"123456\"} }";
2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());
3
if(var->type() == typeid(grammar<char>::object))
4

{
5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);
6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)
7
{
8
std::string strName = (*it).first;
9
10
if((*it).second->type() == typeid(int))
11
{
12
int nValue = boost::any_cast<int>(*(*it).second); //讀到return_code的值0
13
}
14
else if((*it).second->type() == typeid(double))
15
{
16
double dValue = boost::any_cast< double >(*(*it).second); //讀到server_now的值1246117129.8
17
}
18
else if((*it).second->type() == typeid(std::string))
19
{
20
std::string strValue = boost::any_cast< std::string >(*(*it).second);
21
}
22
else if((*it).second->type() == typeid(bool))
23
{
24
bool bValue = boost::any_cast< bool >(*(*it).second);
25
}
26
else if((*it).second->type() == typeid(grammar<char>::object))
27
{
28
//params的值會進入這個判斷語句來
29
30
grammar<char>::object const & o = boost::any_cast<grammar<char>::object>(*(*it).second);
31
for(grammar<char>::object::const_iterator oo = o.begin(); oo != o.end(); ++oo)
32
{
33
std::string strName = (*oo).first; //這里讀到了名稱rekoo_killer
34
35
//下面怎么做我就不寫了,rekoo_killer的值就是一個整型
36
}
37
}
38
else if((*it).second->empty())
39
{
40
AfxMessageBox(_T("it's a null value"));
41
}
42
else
43
{
44
AfxMessageBox(_T("unknown type!"));
45
}
46
}
47
}
相信經過上面的介紹,各位已經對如何使用TinyJSON來讀取一段JSON數據有所了解了。