2010年6月4日 星期五

boost::archive::xml_oarchive 遇上unicode的assert


#include <boost/xml_oarchive.hpp>
#include <sstream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"測試";
ar & boost::serialization::make_nvp("str", str);

return 0;
}


上面這一段程式碼,在debug模式下會出現assert。
這時候將str稍微改一下就正常了。


#include <boost/xml_oarchive.hpp>
#include <sstream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"ABC";
ar & boost::serialization::make_nvp("str", str);

return 0;
}


主要原因是因為locale的關係,在xml_oarchive寫入資料時會透過wctomb將unicode轉成multibyte,此時因為locale不對造成轉換錯誤,而產生assert。
所以只要在使用xml archive前先setlocale就ok了。


#include <boost/xml_oarchive.hpp>
#include <boost/xml_iarchive.hpp>
#include <sstream>
#include <string>
#include <assert>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

{
boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"測試";
ar & boost::serialization::make_nvp("str", str);
}

{
boost::archive::xml_iarchive ar(ss);
std::wstring str;
ar & boost::serialization::make_nvp("str", str);
assert(str == L"測試");
}

return 0;
}


不過,比較好的做法是存檔時先將wchar_t轉成utf-8再交給xml archive,讀檔時再把utf-8轉成wchar_t

LinkWithin

Related Posts with Thumbnails