6

我正在为 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.cppUTF8 -CPPICUDinkumware,但我还没有看到一个可以与我已有的解决方案一起工作的示例(例如,我不希望在这点):

std::wofstream ofs( "myOutputFile" );
boost::archive::text_woarchive oa( ... );
//... what do I put here? ...
oa << myMainClass;

myMainClass包含宽字符串和指向其他类的 Boost 智能指针,这些类反过来会被序列化。

4

2 回答 2

2

wofstreamtypedef basic_ofstream<wchar_t, char_traits<wchar_t> > wofstream;

在 linux 上,您需要声明一个自定义ofstream来处理 16 位字符(在 linux 上)。这可以按如下方式完成:

typedef std::uint16_t Char16_t;
typedef basic_ofstream<Char16_t, char_traits<Char16_t> > wofstream_16;

现在wofstream_16可以在不同平台上无缝使用来处理 16 位宽的字符。

于 2011-12-13T08:22:38.247 回答
0

有一个简单的解决方案对我有用。只需理解官方文档中的这些语句并将它们转换为 C++ 语法即可:

  1. 打开一个宽字符流。
  2. 更改流语言环境以使用 boost::archive::codecvt_null
  3. 使用标志 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 格式存储。

于 2012-07-30T17:32:33.833 回答