c++读取json配置文件

这里写自定义目录标题

conf.h

基于rapidjson封装,只需要引入rapidjson头文件即可使用

#ifndef _CONF_CONF_H
#define _CONF_CONF_H

#include <string>
#include <typeinfo>
#include <vector>

#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<int>& values);
		bool GetArrayInt64(const std::string key, std::vector<int64_t>& values);

		bool GetString(const std::string key, std::string& value);
		bool GetArrayString(const std::string key, std::vector<std::string>& values);

		bool GetDouble(const std::string key, double& value);
		bool GetArrayDouble(const std::string key, std::vector<double>& values);
		bool GetFloat(const std::string key, float& value);
		bool GetArrayFloat(const std::string key, std::vector<float>& values);
		bool GetBool(const std::string key, bool& value);
	private:
		std::vector<std::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 <fstream>
#include <cstdio>
#include <iostream>
#include <rapidjson/error/en.h>
#include <rapidjson/filereadstream.h>

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<char> begin(in);
		std::istreambuf_iterator<char> 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<std::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<std::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<int>& values) {
		if (key.empty()) {
			return false;
		}
		std::vector<std::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<int64_t>& values) {
		if (key.empty()) {
			return false;
		}
		std::vector<std::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<std::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<std::string>& values) {
		if (key.empty()) {
			return false;
		}
		std::vector<std::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<std::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<double>& values) {
		if (key.empty()) {
			return false;
		}
		std::vector<std::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<std::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<float>& values) {
		if (key.empty()) {
			return false;
		}
		std::vector<std::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<std::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<std::string> ConfigParser::SplitKey(const std::string key) {
		//g++版本不支持
		//std::regex re{ "\\." };
		//return std::vector<std::string> {
		//	std::cregex_token_iterator(key.c_str(), key.c_str() + key.length(), re, -1),
		//		std::cregex_token_iterator()
		//};
		std::vector<std::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 <conf/conf.h>
#include <string>
#include <iostream>
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::vector<int>ccc;
	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<double> 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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值