c++jsonプロファイルの読み込み

13863 ワード

カスタムディレクトリのタイトルをここに書きます
  • conf.h
  • conf.cc
  • test.json
  • test.cc
  • 出力:
  • conf.h
    rapidjsonパッケージに基づいて、rapidjsonヘッダファイルを導入するだけで使用できます.
    #ifndef _CONF_CONF_H
    #define _CONF_CONF_H
    
    #include 
    #include 
    #include 
    
    #include "rapidjson/document.h"
    
    namespace conf {
    	class ConfigParser{
    	public:
    		ConfigParser(const std::string& config_path);
    		~ConfigParser();
    
    		bool GetInt(const std::string key, int& value);
    		bool GetInt64(const std::string key, int64_t& value);
    		bool GetArrayInt(const std::string key, std::vector& values);
    		bool GetArrayInt64(const std::string key, std::vector& values);
    
    		bool GetString(const std::string key, std::string& value);
    		bool GetArrayString(const std::string key, std::vector<:string>& values);
    
    		bool GetDouble(const std::string key, double& value);
    		bool GetArrayDouble(const std::string key, std::vector& values);
    		bool GetFloat(const std::string key, float& value);
    		bool GetArrayFloat(const std::string key, std::vector& values);
    		bool GetBool(const std::string key, bool& value);
    	private:
    		std::vector<:string> SplitKey(const std::string key);
    		bool ReadFile(std::string& str);
    	private:
    		const std::string config_path_;
    		rapidjson::Document document_;
    	};
    }  // namespace conf
    
    #endif
    
    

    conf.cc
    #include "conf/conf.h"
    #include 
    #include 
    #include 
    #include 
    #include 
    
    namespace conf {
    
    	ConfigParser::ConfigParser(const std::string& config_path)
    		:config_path_(config_path) {
    
    		std::string str;
    		if (!ReadFile(str)) {
    			std::cerr << "open config file failed." << std::endl;
    			exit(-1);
    		}
    
    		// << str << std::endl;
    		document_.Parse(str.c_str());
    		if (document_.HasParseError()) {
    			std::cerr << "Parse config file failed." << std::endl;
    			exit(-1);
    		}
    	}
    
    	ConfigParser::~ConfigParser() {
    
    	}
    
    
    	bool ConfigParser::ReadFile(std::string & str)
    	{
    		std::ifstream in;
    		std::string line;
    
    		in.open(config_path_, std::ifstream::in);
    		if (!in.is_open())
    			return false;
    
    		std::istreambuf_iterator begin(in);
    		std::istreambuf_iterator end;
    		std::string content(begin, end);
    		str = content;
    
    		return true;
    	}
    
    
    	bool ConfigParser::GetInt(const std::string key, int& value) {
    
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsInt()) {
    			return false;
    		}
    		value = iter->value.GetInt();
    		return true;
    	}
    
    	bool ConfigParser::GetInt64(const std::string key, int64_t& value) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsInt64()) {
    			return false;
    		}
    		value = iter->value.GetInt64();
    		return true;
    	}
    
    	bool ConfigParser::GetArrayInt(const std::string key, std::vector& values) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsArray()) {
    			return false;
    		}
    		auto value = iter->value.GetArray();
    		for (int i = 0; i < value.Size(); ++i) {
    			if (!value[i].IsInt()) {
    				return false;
    			}
    			values.push_back(value[i].GetInt());
    		}
    		return true;
    	}
    
    	bool ConfigParser::GetArrayInt64(const std::string key, std::vector& values) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsArray()) {
    			return false;
    		}
    		auto value = iter->value.GetArray();
    		for (int i = 0; i < value.Size(); ++i) {
    			if (!value[i].IsInt64()) {
    				return false;
    			}
    			values.push_back(value[i].GetInt64());
    		}
    		return true;
    	}
    
    	bool ConfigParser::GetString(const std::string key, std::string& value) {
    
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsString()) {
    			return false;
    		}
    		value = iter->value.GetString();
    		return true;
    	}
    
    	bool ConfigParser::GetArrayString(const std::string key, std::vector<:string>& values) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsArray()) {
    			return false;
    		}
    		auto value = iter->value.GetArray();
    		for (int i = 0; i < value.Size(); ++i) {
    			if (!value[i].IsString()) {
    				return false;
    			}
    			values.push_back(value[i].GetString());
    		}
    		return true;
    	}
    
    	bool ConfigParser::GetDouble(const std::string key, double& value) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsDouble()) {
    			return false;
    		}
    		value = iter->value.GetDouble();
    		return true;
    	}
    
    	bool ConfigParser::GetArrayDouble(const std::string key, std::vector& values) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsArray()) {
    			return false;
    		}
    		auto value = iter->value.GetArray();
    		for (int i = 0; i < value.Size(); ++i) {
    			if (!value[i].IsDouble()) {
    				return false;
    			}
    			values.push_back(value[i].GetDouble());
    		}
    		return true;
    	}
    
    	bool ConfigParser::GetFloat(const std::string key, float& value) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsFloat()) {
    			return false;
    		}
    		value = iter->value.GetFloat();
    		return true;
    	}
    
    	bool ConfigParser::GetArrayFloat(const std::string key, std::vector& values) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsArray()) {
    			return false;
    		}
    		auto value = iter->value.GetArray();
    		for (int i = 0; i < value.Size(); ++i) {
    			if (!value[i].IsFloat()) {
    				return false;
    			}
    			values.push_back(value[i].GetFloat());
    		}
    		return true;
    	}
    
    	bool ConfigParser::GetBool(const std::string key, bool& value) {
    		if (key.empty()) {
    			return false;
    		}
    		std::vector<:string> keys = SplitKey(key);
    		auto keys_size = keys.size();
    
    		rapidjson::Value::ConstMemberIterator iter = document_.FindMember(keys[0].c_str());
    		if (iter == document_.MemberEnd()) {
    			return false;
    		}
    		for (int i = 1; i <= keys_size - 1; ++i) {
    			if (!iter->value.IsObject()) {
    				return false;
    			}
    			auto tmp_iter = iter->value.FindMember(keys[i].c_str());
    			if (tmp_iter == iter->value.MemberEnd()) {
    				return false;
    			}
    			iter = tmp_iter;
    		}
    		if (!iter->value.IsBool()) {
    			return false;
    		}
    		value = iter->value.GetBool();
    		return true;
    	}
    
    
    	std::vector<:string> ConfigParser::SplitKey(const std::string key) {
    		//g++     
    		//std::regex re{ "\\." };
    		//return std::vector<:string> {
    		//	std::cregex_token_iterator(key.c_str(), key.c_str() + key.length(), re, -1),
    		//		std::cregex_token_iterator()
    		//};
    		std::vector<:string> keys;
    
    		if (key.empty())
    		{
    			return keys;
    		}
    
    		std::string pattern = ".";
    
    		std::string strs = key + pattern;
    
    		size_t pos = strs.find(pattern);
    		size_t size = strs.size();
    
    		while (pos != std::string::npos) {
    			std::string sub_key = strs.substr(0, pos);
    			// << sub_key << std::endl;
    			keys.push_back(sub_key);
    			strs = strs.substr(pos + 1, size);
    			pos = strs.find(pattern);
    		}
    		return keys;
    	}
    
    
    }  // namespace conf
    

    test.json
    {
     "aaa":"aaa",
     "bbb":100,
     "ccc":[1,2,3,4],
     "ddd":12.90,
     "eee":[1.1,2.3,3.4],
     "fff":{
     "aaa":"fffaaa"
     }
    }
    

    test.cc
    #include 
    #include 
    #include 
    using namespace std;
    
    int main(){
    	conf::ConfigParser config("D:\\code\\xfmodule_dev\\win\\tests\\conf\\Debug\\test.json");
    	std::string aaa;
    	config.GetString("aaa", aaa);
    	std::cout << "aaa:" << aaa << std::endl;
    
    	int bbb;
    	config.GetInt("bbb", bbb);
    	std::cout << "bbb:" << bbb << std::endl;
    
    	std::vectorccc;
    	config.GetArrayInt("ccc", ccc);
    	for (auto&c : ccc) {
    		std::cout << "c:" << c << std::endl;
    	}
    
    	double ddd;
    	config.GetDouble("ddd", ddd);
    	std::cout << "ddd:" << ddd << std::endl;
    
    	std::vector eee;
    	config.GetArrayDouble("eee", eee);
    	for (auto&e : eee) {
    		std::cout << "e:" << e << std::endl;
    	}
    
    	config.GetString("fff.aaa", aaa);
    	std::cout << "fff.aaa:" << aaa << std::endl;
    
    	system("pause");
    
    	return 0;
    }
    

    出力:
    aaa:aaa
    bbb:100
    c:1
    c:2
    c:3
    c:4
    ddd:12.9
    e:1.1
    e:2.3
    e:3.4
    fff.aaa:fffaaa