使用property_tree进行程序参数的配置

1.boost库版本:boost_1_52_0

2.编译环境:VS2005,win7(32)

3.头文件:CftTree.h

#pragma once
#include <boost/property_tree/ptree.hpp>
#include <string>
#include <Windows.h>

class CfgTree
{
public:
	static boost::property_tree::ptree m_tree;//配置树
protected:
	static std::string m_cfgName;//配置文件名
protected:
	CfgTree(void);
	~CfgTree(void);
public:
	static HMODULE GetCurrentModule();
	static std::string getModleName();
	static std::string CfgTree::getModleDir();
public:
	static bool loadPara();
	static void savePara();
	static std::wstring atow(std::string src);
	static std::string wtoa(std::wstring src);
	static void setConfName(const char *name = "");
	static int getIntPara(std::string key,int v = 0);
	static float getFloatPara(std::string key,float v = 0.0f);
	static std::string getStrPara(std::string key,std::string s="");
};

4.实现文件:CftTree.cpp

#include "CfgTree.h"
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <exception>
#include <iostream>
using namespace std;

std::string CfgTree::m_cfgName = "";
boost::property_tree::ptree CfgTree::m_tree;

CfgTree::CfgTree(void)
{
}

CfgTree::~CfgTree(void)
{
}
bool CfgTree::loadPara()
{
	if (m_cfgName.length()<=0)
	{
		m_cfgName = getModleName();
		m_cfgName += ".xml";
	}
	std::string dirstr = getModleDir();
	dirstr += "\\";
	std::string path = dirstr + m_cfgName;
	

	try
	{
		std::locale cur_loc = std::locale::global(std::locale(""));
		read_xml(path,m_tree,boost::property_tree::xml_parser::trim_whitespace,std::locale(""));
		std::locale::global(cur_loc);
		return true;
	}
	catch (std::exception& e)
	{
		std::locale::global(std::locale("C"));	
		std::cout<<"load cfgfile failed!"<<std::endl;
		std::cout<<e.what()<<std::endl;
	}
	return false;
}
void CfgTree::savePara()
{
	if (m_cfgName.length()<=0)
	{
		m_cfgName = getModleName();
		m_cfgName += ".xml";
	}
	std::string dirstr = getModleDir();
	dirstr += "\\";
	std::string path = dirstr + m_cfgName;

	boost::property_tree::xml_writer_settings<char> settings(' ', 1, "GB2312");
	std::locale cur_loc = std::locale::global(std::locale(""));
	write_xml(path,m_tree,std::locale(""),settings); 
	std::locale::global(cur_loc);
	std::cout<<"save para"<<std::endl;
}
int CfgTree::getIntPara(std::string key,int v)
{
	boost::optional<int> pi = m_tree.get_optional<int>(key);
	if (pi)
	{
		return *pi;
	}
	else
	{
		m_tree.put(key,v);
		return v;
	}
}
float CfgTree::getFloatPara(std::string key,float v)
{
	boost::optional<float> pi = m_tree.get_optional<float>(key);
	if (pi)
	{
		return *pi;
	}
	else
	{
		m_tree.put(key,v);
		return v;
	}
}
std::string CfgTree::getStrPara(std::string key,std::string s)
{
	boost::optional<std::string> pi = m_tree.get_optional<std::string>(key);
	if (pi)
	{
		return *pi;
	}
	else
	{
		m_tree.put(key,s);
		return s;	
	}
}

std::wstring CfgTree::atow(std::string src)
{
	WCHAR *wstr = new WCHAR[src.length()+1];
	MultiByteToWideChar( CP_ACP, 0, src.c_str(),(int)src.length()+1
		, wstr, (src.length()+1)*sizeof(WCHAR) );
	std::wstring ws = wstr;
	delete []wstr;
	return ws;
}
std::string CfgTree::wtoa(std::wstring src)
{
	DWORD len = WideCharToMultiByte(CP_OEMCP,NULL,src.c_str(),-1,NULL,0,NULL,FALSE);
	char *str = new char[len+1];
	WideCharToMultiByte( CP_OEMCP, 0, src.c_str(), -1,
		str, len+1, NULL, NULL );
	std::string as = str;
	delete []str;
	return as;
}

void CfgTree::setConfName(const char *name)
{
	std::string str = name;
	if (str.length()<=0)
	{
		m_cfgName = getModleName();
		m_cfgName += ".xml";
	}
	else
	{
		m_cfgName = name;
	}
}

std::string CfgTree::getModleDir()
{
	WCHAR modeName[MAX_PATH];
	memset(modeName,0,MAX_PATH*sizeof(WCHAR));
	::GetModuleFileNameW(CfgTree::GetCurrentModule(),modeName,MAX_PATH);  
	for (size_t i=wcslen(modeName);i>0;i--)
	{
		if (modeName[i-1] == L'\\'|| modeName[i-1] == L'/')
		{
			modeName[i-1] = L'\0';
			break;
		}
	}
	std::wstring dirstr = modeName;
	return wtoa(dirstr);
}

std::string CfgTree::getModleName()
{
	WCHAR modeName[MAX_PATH];
	memset(modeName,0,MAX_PATH*sizeof(WCHAR));
	::GetModuleFileNameW(CfgTree::GetCurrentModule(),modeName,MAX_PATH);  

	WCHAR Name[100];
	memset(Name,0,100*sizeof(WCHAR));
	size_t from = 0;
	size_t to = 0;
	for (size_t i=wcslen(modeName)-1;i>=0;i--)
	{
		if (modeName[i] == L'\\'|| modeName[i] == L'/')
		{
			from = i;
			break;
		}
		else if (modeName[i]==L'.')
		{
			to = i;
		}
	}
	if (to>from && from>=0)
	{
		memcpy(Name,modeName+from+1,(to-from-1)*sizeof(WCHAR));
		return CfgTree::wtoa(Name);
	}
	return "";
}


#if   _MSC_VER   >=   1300 
#ifndef   _delayimp_h 
extern   "C"   IMAGE_DOS_HEADER   __ImageBase; 
#endif 
#endif 

HMODULE   CfgTree::GetCurrentModule() 
{ 
#if   _MSC_VER   <   1300   
	MEMORY_BASIC_INFORMATION   mbi; 
	static   int   dummy; 
	VirtualQuery(   &dummy,   &mbi,   sizeof(mbi)   ); 

	return   reinterpret_cast <HMODULE> (mbi.AllocationBase); 
#else       
	return   reinterpret_cast <HMODULE> (&__ImageBase); 
#endif 
}

5.使用示例:boostTreeTest.cpp

 

#include "stdafx.h"
#include "CfgTree.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	bool re = CfgTree::loadPara();
	CfgTree::getIntPara("Para.testInt",1);
	CfgTree::getFloatPara("Para.testFloat",1.1);
	CfgTree::getStrPara("Para.testStr","ab   /  c");
	if (!re)
	{
		CfgTree::savePara();
	}

	int key = 0;
	while(true)
	{
		cout<<"1:save"<<endl;
		cout<<"2:read"<<endl;
		cin>>key;

		if (key==1)
		{
			CfgTree::savePara();
		}
		else if (key==2)
		{
			CfgTree::loadPara();
		}
	}
	return 0;
}


 6.实现要点:

6.1注意locale:

系统默认为“std::locale("C")”,property_tree使用“std::locale("")”;可先将全局locale设为“std::locale("")”,调用完“read_xml”或“write_xml”后恢复为"“std::locale("C")”.

"std::locale::global()"可设置当前locale,其返回值为设置前的locale。

6.2注意"write_xml"格式:

可通过“boost::property_tree::xml_writer_settings<char> settings(' ', 1, "GB2312");"进行设置。

6.3注意“read_xml”去空格:

使用“boost::property_tree::xml_parser::trim_whitespace”可去掉空格等无用字符。

 

你可能感兴趣的:(使用property_tree进行程序参数的配置)