天天看點

C++ json庫jsoncpp 吐槽(轉)

  • Author:Echo Chen(陳斌)
  • Email:[email protected]
  • Blog:Blog.csdn.net/chen19870707
  • Date:September 28th, 2014

Explain

     最近在做遊戲接入SDK時用到C++的json庫jsoncpp,jsoncpp 是一款優秀的json庫,但惡心的一點是它采用Assert作為錯誤處理方法,而assert在Linux下通過調用 abort 來終止程式運作,對于伺服器而言将會收到SIGABRT,崩潰打出core,這對于伺服器而言是緻命的,下面總結了幾種 Assertion `type_ == nullValue || type_ == object Value' failed的情況。

1. json字元串不合法

1: Json::Reader *pJsonParser = new Json::Reader();      
2: string strJson = "1111 {}";        //不合法json      
3:        
4: Json::Value tempVal;      
5:        
6: if(!pJsonParser->parse(strJson, tempVal))      
7: {      
8:     cout << "parse error" << endl;      
9:     return -1;      
10: }      
11: string name = tempVal["name"].asString();      
由于Jsoncpp解析非法json時,會自動容錯成字元類型。對字元類型取下标時,會觸發assert終止程序。      
解決方法:啟用嚴格模式,讓非法的json解析時直接傳回false,不自動容錯。這樣,在調用parse的時候就會傳回false。      
1: Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());      

2.解析串為json數組

1: Json::Reader *pJsonParser = new Json::Reader();      
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\',\'sex\':\'男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";      
3:        
4: Json::Value tempVal;      
5:        
6: if(!pJsonParser->parse(strJson, tempVal))      
7: {      
8:     return -1;      
9: }      
10:        
11: string friendsName = tempVal["friends"]["name"].asString();      

由于friends為數組,直接取name,會Assertion `type_ == nullValue || type_ == objectValue' failed.

解決方法:循環讀取數組

1: Json::Value friends = tempVal["friends"];      
2: for(int i = 0;i < friends.size();i++)      
3: {      
4:     cout << friends[i]["name"].asString() << endl;      
5: }      

3.轉型錯誤

1: Json::Reader *pJsonParser = new Json::Reader();      
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";      
3: Json::Value tempVal;      
4: if(!pJsonParser->parse(strJson, tempVal))      
5: {      
6:     return -1;      
7: }      
8: int name = tempVal["name"].asInt();      

解決方法:先判斷類型,如果類型正确在取

1: if(tempVal["name"].isInt())      
2: {      
3:        
4:     int name = tempVal["name"].asInt();      
5: }      

對于SDK接入認證伺服器而言,json解析完全依賴于管道SDK傳過來的SDK,jsoncpp過于依賴json字元串,如果對端傳過來一個不合法的json,很容易引起認證伺服器的崩潰,是以對于SDK認證而言,采用C++來解析json是一個不太好的選擇,此外SDK中的demo一般都隻提供PHP或Python的源代碼,還得自己翻譯,不太劃算,後面的SDK準備都采用php的方式進行接入。

Jsoncpp讀寫執行個體代碼

    這裡Mark一下jsoncpp的讀寫執行個體代碼:

1. Read

1: #include <iostream>      
2: #include "json/json.h"      
3: #include <string>      
4: using namespace std;      
5:        
6: int main()      
7: {      
8:     Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());      
9:     //Json::Reader *pJsonParser = new Json::Reader();      
10:     string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";      
11:     //string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":{\'name\':\'chen\',\'sex\':\'男\'}}";      
12:     //string strJson = "1111 {}";      
13:        
14:     Json::Value tempVal;      
15:        
16:        
17:     if(!pJsonParser->parse(strJson, tempVal))      
18:     {      
19:         cout << "parse error" << endl;      
20:         return -1;      
21:     }      
22:        
23:     string name = tempVal["name"].asString();      
24:     string sex = tempVal["sex"].asString();      
25:     string age = tempVal["age"].asString();      
26:        
27:     Json::Value friends = tempVal["friends"];      
28:     for(int i = 0;i < friends.size();i++)      
29:     {      
30:         cout << friends[i]["name"].asString() << endl;      
31:     }      
32:        
33:     cout << "name = " << name << "    age = " << age << "    sex = " << sex << "    friendsName    " << friendsName <<endl;      
34:        
35:     delete pJsonParser;      
36:        
37:     return 0;      
38: }      
39:        

2.Write

1: #include <fstream>      
2: #include <cassert>      
3: #include "json/json.h"      
4: using namespace std;      
5:        
6: int main()      
7: {      
8:     Json::Value root;      
9:     Json::FastWriter writer;      
10:     Json::Value person;      
11:        
12:     person["name"] = "hello world";      
13:     person["age"] = 100;      
14:     root.append(person);      
15:        
16:     std::string json_file = writer.write(root);      
17:        
18:        
19:     ofstream ofs;      
20:     ofs.open("test1.json");      
21:     assert(ofs.is_open());      
22:     ofs<<json_file;      
23:        
24:     return 0;      
25: }      

轉載于:https://www.cnblogs.com/huojing/articles/5927488.html