4

アプリケーションに仮想UTF-8環境を提供するmingwで使用するラッパーレイヤーを作成しています。ファイル名を処理する関数は、UTF-8から変換し、対応する「_w」関数などを呼び出すラッパーです。私が遭遇した大きな問題は、Windowswchar_tが16ビットであるということです。

ファイルシステム操作の場合、それは大したことではありません。UTF-8とUTF-16の間で変換するだけで、すべてが機能します。ただし、標準のCマルチバイト/ワイド文字変換APIでは、multi-wchar_t文字は使用できません。

可能な解決策:

  1. UTF-8の代わりにCESU-8環境を提供します。私はこれが本当に好きではありません。
  2. 簡単な方法でBMPのみをサポートしてください。長さ4のUTF-8シーケンスを無効として扱います。
  3. ラッパーを拡張して、mingwを置き換えwchar_ttypedef int32_t wchar_t;処理しWCHARwchar_t異なるものにします。これは面倒ですが、クリーンなPOSIXタイプの環境を期待し、wchar_tWindows-APIの目的には使用しないアプリを移植するのに理想的かもしれません。
  4. 次のハック:

mbrtowcwchar_t4バイトのUTF-8文字の最初の3バイトを読み取った後、上位サロゲートに対応するを出力し、残りの状態をmbstate_tオブジェクトに保持します。次のバイトを受信すると、それを保存された状態と組み合わせて、下位サロゲートを出力します。最後のバイトが無効になると、-1が返され(EILSEQを使用)、1つのサロゲートが出力ストリームに含まれます(不良...)。

wcrtomb上位サロゲートを処理するときにUTF-8の最初の2バイトを出力し、残りの状態をmbstate_tオブジェクトに保存します。その後、下位サロゲートを処理するときに、それを保存された状態と組み合わせて、UTF-8の最後の2バイトを出力します。有効なローサロゲートが受信されない場合、-1が返され(EILSEQを使用)、不完全なUTF-8シーケンスが出力ストリームに残ります(不良...)。

このハックのプラス面は、入力が有効である限り機能し、UTF-8文字、つまり可能なファイル名/引数などにアクセスできることです。アプリケーションが処理する必要のあるテキスト。

短所は、ISO Cに厳密に準拠しておらず(wchar_t文字列をステートフルにすることは許可されていません)、誤った部分出力がすでに書き込まれるまで、不正な形式の文字の検出を遅らせることです。

私はさまざまなオプション、特に提案されたハックについてのフィードバックを探しています:それが合理的かどうか、短所が重大なエラーを引き起こす可能性があるかどうか、そしてスキームを妨げる可能性のある他の短所があるかどうか完全に機能します。また、私が考えていなかった他の可能な解決策を聞いてうれしいです。

4

2 に答える 2

2

#4のようなことをしますが、入力が有効であることが確認されるまで出力を生成しません。

  • mbrtowc文字全体をデコードする必要があります。BMPの外側にある場合は、高サロゲートを出力し、低サロゲートをに格納しmbstate_tます。
  • wcrtombに上位のサロゲートを格納しmbstate_t、文字が有効な場合は4UTF-8バイトすべてを出力する必要があります。
于 2010-07-13T06:20:23.310 に答える
0

Windowsを使用している場合は、MultiByteToWideCharとWideCharToMultiByteを使用して、一度に文字列全体をUTF-16とUTF-8の間で変換します。

GCCのデフォルトモードは32ビットwchar_tですが、これを変更するコンパイルスイッチがあり、より一般的には、cおよびc ++の仕様ではwchar_tのサイズが指定されていません。実際、wchar_tはcharと同じサイズにすることができます。

(Windowsラッパーコードで!?)Windows APIの使用を避けたい場合は、mbstowcsを使用して一度に文字列全体を変換します。

于 2010-07-12T13:30:23.770 に答える