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;
- }