我在一个为Windows(使用Visual Studio 2008)和Mac(使用GCC)构建的程序中使用Boost C ++库实现序列化。该程序在其大约30个类中使用宽字符串(std::wstring
)。根据平台的不同,当我保存到文件(通过boost::archive::text_woarchive
)时,宽字符串在输出文件中的表示方式不同。
保存在 Windows :
下H*e*l*l*o* *W*o*r*l*d*!* ...
保存在 MacOSX :
下H***e***l***l***o*** ***W***o***r***l***d***!*** ...
其中*是NULL字符。
当我尝试使用Mac版本读取在Windows下创建的文件时(反之亦然),我的程序崩溃了。
根据我的理解,到目前为止,Windows本身使用每个宽字符2个字节,而MacOSX(我认为通常使用Unix)使用4个字节。
我遇到了utf8_codecvt_facet.cpp
,UTF8-CPP,ICU和Dinkumware等可能的解决方案,但是我还没有看到一个例子这将与我已经拥有的东西一起工作(例如,我不希望在此时重写五个月的序列化工作):
std::wofstream ofs( "myOutputFile" );
boost::archive::text_woarchive oa( ... );
//... what do I put here? ...
oa << myMainClass;
myMainClass
包含宽字符串和Boost智能指针,这些指针反过来会被序列化。
答案 0 :(得分:2)
wofstream
是typedef basic_ofstream<wchar_t, char_traits<wchar_t> > wofstream;
ofstream
来处理16位字符(在Linux上)。
这可以按如下方式完成:
typedef std::uint16_t Char16_t;
typedef basic_ofstream<Char16_t, char_traits<Char16_t> > wofstream_16;
现在wofstream_16
可以在不同平台上无缝使用,以处理16位宽字符。
答案 1 :(得分:0)
有一个简单的解决方案对我有用。这只是在official documentation中理解这些语句并将它们转换为C ++语法的问题:
- 打开一个宽字符流。
- 更改流语言环境以使用boost :: archive :: codecvt_null
- 使用标记no_codecvt创建存档。
醇>
所以一起看起来像这样(输出到文件):
#include <fstream>
#include <locale>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/text_woarchive.hpp>
#include <boost/archive/text_wiarchive.hpp>
// (1)
std::wofstream ofs( "myOutputFile.dat" );
// (2)
std::locale loc( ofs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ofs.imbue( loc );
// (3) (note text_woarchive)
boost::archive::text_woarchive oa( ofs, boost::archive::no_codecvt );
oa << myMainClass;
同样的想法适用于文件输入:
std::wifstream ifs( "myInputFile.dat" );
std::locale loc( ifs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ifs.imbue( loc );
boost::archive::text_wiarchive ia( ifs, boost::archive::no_codecvt );
ar >> myMainClass;
两个平台上的输出文件现在都相同,并存储为UTF8。