6

Windows (Visual Studio 2008 を使用) および Mac (GCC を使用) 用にビルドされたプログラムで、Boost C++ ライブラリを使用してシリアル化を実装しています。std::wstringこのプログラムは、約 30 のクラスでワイド文字列 ( ) を使用しています。プラットフォームによっては、( を使用して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などの可能なソリューションに出くわしましたが、既に持っているもので機能する例をまだ見ていません(たとえば、5 か月の連載作業をこの点):

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;

ofstreamLinux では、 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 に答える