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”可去掉空格等无用字符。