boost::property_tree读取解析ini文件
#include "stdafx.h"
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
int main()
{
boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("D:\\Overlay.ini", pt);
std::cout << pt.get<std::string>("OVERLAY.OverlayFontName") << std::endl;
pt.put<std::string>("OVERLAY.OverlayFontName","宋体");
std::cout << pt.get<std::string>("OVERLAY.OverlayFontName") << std::endl;
boost::property_tree::ini_parser::write_ini("D:\\Overlay.ini",pt);
return 0;
}
在C++11下,宽字节和单字节转换就简单了。使用std::wstring_convert和std::codecvt_utf8 来处理UTF8与WChar之间的互转.
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
#include <fstream>
int main(int argc, char *argv[])
{
std::wstring str = L"123,宋体!";
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::string narrowStr = conv.to_bytes(str);
{
std::ofstream ofs ("c:\\test.txt");
ofs << narrowStr;
}
std::wstring wideStr = conv.from_bytes(narrowStr);
{
std::locale::global(std::locale("Chinese-simplified"));
std::wofstream ofs (L"c:\\testW.txt");
ofs << wideStr;
}
}
另外可以保存函数,使用ptree:
1 struct debug_simple 2 { 3 int itsNumber; 4 std::string itsName; //这里使用string就可以 5 void load(const std::string& filename); //载入函数 6 void save(const std::string& filename); //保存函数 7 };
保存函数,使用ptree:
1 void debug_simple::save( const std::string& filename ) 2 { 3 using boost::property_tree::ptree; 4 ptree pt; 5 6 pt.put("debug.number",itsNumber); 7 pt.put("debug.name",itsName); 8 9 write_xml(filename,pt); 10 }
载入函数使用的wptree,读取的值为wstring,需转换成string
1 void debug_simple::load( const std::string& filename ) 2 { 3 using boost::property_tree::wptree; 4 wptree wpt; 5 read_xml(filename, wpt); 6 7 itsNumber = wpt.get<int>(L"debug.number"); 8 std::wstring wStr = wpt.get<std::wstring>(L"debug.name"); 9 itsName = std::string(wStr.begin(),wStr.end()); //wstring转string 10 }
main函数:1 int _tmain(int argc, _TCHAR* argv[]) 2 { 3 4 try 5 { 6 debug_simple ds,read; 7 ds.itsName = "汉字english"; 8 ds.itsNumber = 20; 9 10 ds.save("simple.xml"); 11 read.load("simple.xml"); 12 13 std::cout<<read.itsNumber<<read.itsName; 14 15 } 16 catch (std::exception &e) 17 { 18 std::cout << "Error: " << e.what() << "\n"; 19 } 20 return 0; 21 }
由于.ini文件是utf-8格式的,所以操作时要utf-8到unicode转换,或unicode到utf-8转换;
// PropertyTree.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
//unicode 转UTF8
//参数1是UTF8字符串当前位置指针,这里必须要是指针,因为必须要通过第1个字符进行判断才知道一个完整的字符的编码要向后取多少个字符
//参数2是返回的UCS-2编码的Unicode字符
inline int UTF82UnicodeOne(const char* utf8, wchar_t& wch)
{
if (utf8==NULL)
{
return -1;
}
//首字符的Ascii码大于0xC0才需要向后判断,否则,就肯定是单个ANSI字符了
unsigned char firstCh = utf8[0];
if (firstCh >= 0xC0)
{
//根据首字符的高位判断这是几个字母的UTF8编码
int afters, code;
if ((firstCh & 0xE0) == 0xC0)
{
afters = 2;
code = firstCh & 0x1F;
}
else if ((firstCh & 0xF0) == 0xE0)
{
afters = 3;
code = firstCh & 0xF;
}
else if ((firstCh & 0xF8) == 0xF0)
{
afters = 4;
code = firstCh & 0x7;
}
else if ((firstCh & 0xFC) == 0xF8)
{
afters = 5;
code = firstCh & 0x3;
}
else if ((firstCh & 0xFE) == 0xFC)
{
afters = 6;
code = firstCh & 0x1;
}
else
{
wch = firstCh;
return 1;
}
//知道了字节数量之后,还需要向后检查一下,如果检查失败,就简单的认为此UTF8编码有问题,或者不是UTF8编码,于是当成一个ANSI来返回处理
for(int k = 1; k < afters; ++ k)
{
if ((utf8[k] & 0xC0) != 0x80)
{
//判断失败,不符合UTF8编码的规则,直接当成一个ANSI字符返回
wch = firstCh;
return 1;
}
code <<= 6;
code |= (unsigned char)utf8[k] & 0x3F;
}
wch = code;
return afters;
}
else
{
wch = firstCh;
}
return 1;
}
//参数1是UTF8编码的字符串
//参数2是输出的UCS-2的Unicode字符串
//参数3是参数1字符串的长度
//使用的时候需要注意参数2所指向的内存块足够用。其实安全的办法是判断一下pUniBuf是否为NULL,如果为NULL则只统计输出长度不写pUniBuf,这样
//通过两次函数调用就可以计算出实际所需要的Unicode缓存输出长度。当然,更简单的思路是:无论如何转换,UTF8的字符数量不可能比Unicode少,所
//以可以简单的按照sizeof(wchar_t) * utf8Leng来分配pUniBuf的内存……
int UTF82Unicode(const char* utf8Buf, wchar_t *pUniBuf, int utf8Leng)
{
if ((utf8Buf==NULL)||(pUniBuf==NULL))
{
return -1;
}
int i = 0, count = 0;
while(i < utf8Leng)
{
i += UTF82UnicodeOne(utf8Buf + i, pUniBuf[count]);
count ++;
}
return count;
}
inline int Unicode2UTF8One(unsigned wchar, char *utf8)
{
if (utf8==NULL)
{
return -1;
}
int len = 0;
if (wchar < 0xC0)
{
utf8[len ++] = (char)wchar;
}
else if (wchar < 0x800)
{
utf8[len ++] = 0xc0 | (wchar >> 6);
utf8[len ++] = 0x80 | (wchar & 0x3f);
}
else if (wchar < 0x10000)
{
utf8[len ++] = 0xe0 | (wchar >> 12);
utf8[len ++] = 0x80 | ((wchar >> 6) & 0x3f);
utf8[len ++] = 0x80 | (wchar & 0x3f);
}
else if (wchar < 0x200000)
{
utf8[len ++] = 0xf0 | ((int)wchar >> 18);
utf8[len ++] = 0x80 | ((wchar >> 12) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 6) & 0x3f);
utf8[len ++] = 0x80 | (wchar & 0x3f);
}
else if (wchar < 0x4000000)
{
utf8[len ++] = 0xf8 | ((int)wchar >> 24);
utf8[len ++] = 0x80 | ((wchar >> 18) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 12) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 6) & 0x3f);
utf8[len ++] = 0x80 | (wchar & 0x3f);
}
else if (wchar < 0x80000000)
{
utf8[len ++] = 0xfc | ((int)wchar >> 30);
utf8[len ++] = 0x80 | ((wchar >> 24) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 18) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 12) & 0x3f);
utf8[len ++] = 0x80 | ((wchar >> 6) & 0x3f);
utf8[len ++] = 0x80 | (wchar & 0x3f);
}
return len;
}
//
int Unicode2UTF8( const wchar_t *pUniBuf,char* utf8Buf, int UniLeng)
{
if ((utf8Buf==NULL)||(pUniBuf==NULL))
{
return -1;
}
int count = 0, i = 0;
while(i < UniLeng)
{
count += Unicode2UTF8One(pUniBuf[i], utf8Buf+count);
i ++;
}
return count;
}
int main()
{
boost::property_tree::ptree pt;
using boost::property_tree::wptree;
wptree wpt;
boost::property_tree::ini_parser::read_ini("D:\\Overlay.ini", pt);
std::string fontName=pt.get<std::string>("OVERLAY.OverlayFontName") ;
wchar_t wfontName[128]={0};
UTF82Unicode(fontName.c_str(),wfontName,fontName.length());
std::wstring wstrfontName=wfontName;
//std::wcout << wstrfontName.c_str()<< std::endl;
/*std::wstring */
wstrfontName=_T("我是谁");
char cfontName[128]={0};
Unicode2UTF8(wstrfontName.c_str(),cfontName,wstrfontName.length());
pt.put<std::string>("OVERLAY.OverlayFontName",cfontName);
//std::cout << pt.get<std::string>("OVERLAY.OverlayFontName") << std::endl;
boost::property_tree::ini_parser::write_ini("D:\\Overlay.ini",pt);
return 0;
}