Json::Value 可以表示所有類型
Json::Reader 將json文件流或字符串解析到Json::Value,主要調用函數parse()
Json::Writer 將Json::Value轉化爲字符串流
若json文件是utf8格式,因爲utf8用BOM表明編碼格式,又叫utf-8的簽名,意思是告訴編譯器當前文件採用何種編碼格式,但是BOM會產生輸出,若接受者收到以EF BB BF開頭的字節流,就是以utf-8格式編碼的,在讀取json文件時候需要去掉BOM
使用jsoncpp前提:包含jsoncpp的靜態鏈接庫,鏈接的時候需要連接庫 -ljsoncpp,頭文件包含需要用相對路徑
絕對路徑就是文件的真正存在的路徑,是指從硬盤的根目錄(盤符)開始,進行一級級目錄指向文件
相對路徑就是以當前文件爲基準進行一級級目錄指向被引用的資源文件
JSON文件:
{
"scene_id" : 40012,
"name" : "戰盟廣場",
"relive" : {
"type" : "1100",//復活類型
"relive_item" : 200000016,//復活使用的道具
"wait" : 2, //復活等待時間
"multi_point" : [[5,40]],//多個復活點隨機選擇
"state" : [100] //隨機點復活
},
"layout":[{
"born_type" : "center",
"monster_sort" : 507100601, // 戰盟廣場普通小偷
"patrol_path" : [[29.85,26.9],[31.1,36.2],[36.9,33.25],[27.65,32.3],[34.7,26.9],[37.45,30.6],[33.8,36.2],[29.9,26.9]]//小怪行走路徑
},
{
"born_type" : "center",
"monster_sort" : 507100606, // 戰盟廣場精英小偷
"monster_name" :1,
"monster_tree" : "bev1002.json",// 行爲樹
"space" : 1, // BOSS所在的分線
"is_rand_center":1, //從 center_coordxy 中隨機取出兩個連續的點爲BOSS的出生座標,存在即可
"select_c_radius":3,//視野範圍,默認8
"move_interval":2,//巡邏週期,默認4-7秒
"rand_move_radius":3,//巡邏範圍,默認3
"idle_back_distance":30,//追擊範圍,默認18
"born_count" : 1,
"born_range" : 0,
"center_coordxy" : [12.1,21.8,29.55,9.1,51.95,23.9,44.55,50.2,22.8,51.95],//B精英小偷出生點
"skill_set" : [409000001]
}
],
"all_reward":
{
//所有參與的玩家獲得的獎勵
"item_reward":[[200000058, 4, 2],[200000060, 3, 2]]
}
}
/*
* load_json.cpp
*
* Created on: 2017年9月14日
* Author: guojing
*/
#include<iostream>
#include<json/json.h>
#include<json/reader.h>
#include<json/value.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
using namespace std;
const unsigned char *skipBOM(const unsigned char *str, int *size)
{
const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
const unsigned char *c = (const unsigned char *)str;
int i = 0;
do {
if (i > *size)
break;
if (*c != *(const unsigned char *)p++)
{
*size -= i;
return c;
}
++i;
++c;
} while (*p != '\0');
*size -= i;
return c;
}
int load_json_config(const char *doc,::Json::Value &conf)
{
int file=::open(doc,O_RDONLY);
if(file<0)
return -1;
struct stat statbuf;
if(::fstat(file,&statbuf)<0)
return -1;
void *src=0;
if((src=::mmap(0,statbuf.st_size,PROT_READ,MAP_PRIVATE,file,0))==MAP_FAILED)
{
return -1;
}
int skip_src_size = statbuf.st_size;
const unsigned char *skip_src = skipBOM((const unsigned char *)src, &skip_src_size);//去掉utf8的BOM編碼標籤
::Json::Reader reader;
if(reader.parse((const char*)skip_src,(const char*)(skip_src+skip_src_size),conf)==false)
{
return -1;
}
if (::munmap(src, statbuf.st_size) < 0)
{
return -1;
}
::close(file);
return 0;
}
int main()
{
//讀取json文件
::Json::Value conf;
load_json_config("s40012.json",conf);
if(!conf.empty())
{
cout<<conf["relive"]["multi_point"][0u][0u].asInt()<<endl;
cout<<conf["relive"]["multi_point"][0u][1u].asInt()<<endl;
int size=conf["layout"].size();
for(int index=0;index<size;index++)
{
cout<<conf["layout"][index]["monster_sort"].asInt()<<endl;
}
}
return 0;
}
Json讀取中的一些坑:可以通過getMemberNames()得到json文件中的所有外層key
const Json::Value& all_cfg = CONFIG_INSTANCE->mythical();
for(Json::Value::Members::iterator ite=all_cfg.getMemberNames().begin();ite!=all_cfg.getMemberNames().end();ite++)
{
MSG_USER("%s",(*ite).c_str());
Int64 monster_id=::atoi(ite->c_str());}
上面這樣寫會有一個偶發性讀取不到正確key的BUG存在
正確寫法:
const Json::Value& all_cfg = CONFIG_INSTANCE->mythical();
Json::Value::Members members=all_cfg.getMemberNames();
for(Json::Value::Members::iterator ite=members.begin();ite!=members.end();ite++)
{
MSG_USER("%s",(*ite).c_str());
Int64 monster_id=::atoi(ite->c_str());
}
直接迭代json文件中所有鍵值對,通過迭代器.key().asCString()獲得對應的鍵,iter直接就是json文件中key所對應的完整的值
void GameConfig::BasicConfig::convert_json_to_map(int debug_flag)
{
this->revert_map().unbind_all();
for (Json::Value::iterator iter = this->revert_json().begin();
iter != this->revert_json().end(); ++iter)
{
Json::Value *json = &(*iter);
this->revert_map().rebind(::atoi(iter.key().asCString()), json);
JUDGE_CONTINUE(debug_flag == true);
MSG_DEBUG("Key: %s,%s", iter.key().asCString(),json->toStyledString().c_str());
}
}