2012-10-26 11 views
10

私はWindowsでテキストサポートを実装しようとしており、後でLinuxプラットフォームに移行する予定です。国際的な言語を統一的にサポートすることは理想的ですが、問題の2つのプラットフォームを考慮すると容易には実現できないようです。私はUNICODE、UTF-8(および他のエンコーディング)、widecharsなどを読んでかなりの時間を費やしてきましたが、これまでに理解したことがあります:ユニコード、UTF-8、Windowsの混乱

UNICODEは、マッピング可能な文字とその順序が表示されます。私はこれを "何"と呼んでいるのですか:ユニコードはを指定しています。何がになるでしょうか。

UTF-8(および他のエンコーディング)は、の指定方法を指定します。:各文字のバイナリ形式の表現方法。

Windowsでは、もともとはUCS-2エンコーディングを選択していましたが、要件を満たせなかったため、UTF-16が必要です。だからここ

はdelemmaです:

  1. は、Windowsは、内部のみUTF-16を行いますので、あなたは、国際的な文字をサポートしたい場合は、OSがそれに応じて呼び出しを使用するために彼らのWIDECHARバージョンに変換することを余儀なくされています。 CreateFileA()のようなものをマルチバイトのUTF-8文字列で呼び出すことは適切ではないようです。これは正しいです?
  2. Cでは、いくつかのマルチバイトのサポート関数(_mbscat、_mbscpyなど)がありますが、ウィンドウでは文字型はunsigned char *として定義されています。 _mbsの一連の関数が完全なセットではないという事実(例えば、マルチバイト文字列をlongに変換するための_mbstolはありません)を考えると、ランタイム関数のchar *バージョンのいくつかを強制的に使用することになります。これらの関数間の符号付き/符号なし型の違いにより、コンパイラの問題が発生します。誰もそれらを使用していますか?あなたはエラーを回避するために鋳造の大きな山をしていますか?
  3. C++では、std :: stringにはイテレータがありますが、これはコードポイントではなくchar_typeに基づいています。したがって、私がstd :: string :: iteratorで++を実行した場合、次のコードポイントではなく次のchar_typeを取得します。同様に、std :: string :: operator []を呼び出すと、完全なコードポイントではない可能性のあるchar_typeへの参照が得られます。だから、コードポイントでstd :: stringをどのように反復するのでしょうか? (Cには_mbsinc()関数があります)。
+1

「必要に応じてマルチバイト」ではありません。それはちょうど "マルチバイト"です。あなたがそれを処理し始めるまで、それが「必要」かどうかは分かりません。 –

+0

ここにはこの件に関する[私の投稿](http://stackoverflow.com/questions/6300804/wchars-encodings-standards-and-portability)があります。おそらくそれはあなたの興味です。 (3)では、あなたのデータをUTF-32(理想的には 'char32_t'に格納されている)に変換し、コードポイントは文字列要素と同じです。 –

+3

また、コードポイントでUnicode文字列を反復する正当な理由はほとんどないことに留意してください。なぜなら、書記素は複数のコードポイント(それぞれがUTF-8またはUTF-16で複数のコードユニットになることができますが、多くの実用的な目的は同じ問題を二度繰り返す)。正規化は正当な理由の1つで、UTF-8へのエンコーディングは別のものですが、これらはあなたがライブラリを使用できるものです。 –

答えて

6
  1. 正しい。あなたは、あなたのWindows API呼び出しのためにUTF-8をUTF-16に変換します。

  2. あなたはUTF-8のための定期的な文字列関数を使用するほとんどの時間 - 、(ICK)strcpystrlensnprintfstrtol。 UTF-8文字で正常に動作します。 UTF-8にchar *を使用するか、すべてをキャストする必要があります。

    _mbstowcsのようなアンダースコアのバージョンは標準ではありませんが、通常はアンダースコアなしの名前が付けられます(mbstowcsなど)。

  3. 実際にoperator[]をUnicode文字列に使用する場合の例はありません。私はそれを避けることを勧めます。同様に、文字列を反復処理すると、驚くほど少数の用途があります:

    • あなたは文字列を解析している場合(例えば、文字列はCやJavaScriptコードで、多分あなたは、構文hilightingをしたい)、あなたは仕事のバイトのほとんどを行うことができますバイバイ・アスペクトを無視します。

    • 検索を行う場合は、これもバイト単位で行います(ただし、最初に正規化することを忘れないでください)。

    • 単語区切りまたはグラフェムクラスターの境界を探している場合は、ICUのようなライブラリを使用することをお勧めします。アルゴリズムは単純ではありません。

    • 最後に、テキストの塊をいつでもUTF-32に変換してそのまま使用できます。私は照合や壊滅のようなUnicodeアルゴリズムのいずれかを実装しているなら、これが最も良いオプションだと思います。

    参照:C++ iterate or split UTF-8 string into array of symbols?

2
  1. Windowsが内部的にのみUTF-16を行いますので、あなたは、国際的な文字をサポートしたい場合は、OSがそれに応じて呼び出しを使用するために彼らのWIDECHARバージョンに変換することを余儀なくされています。 CreateFileA()のようなものをマルチバイトのUTF-8文字列で呼び出すことは適切ではないようです。これは正しいです?

はい、正しいです。 *A関数のバリエーションは、現在アクティブなコードページ(米国および西ヨーロッパのほとんどのコンピュータでWindows-1252ですが、しばしば他のコードページになることがあります)に従って文字列パラメータを解釈し、UTF-16に変換します。 UTF-8コードページがありますが、AFAIKではアクティブなコードページをプログラムで設定する方法はありません(GetACPがアクティブコードページを取得しますが、対応するSetACPはありません)。Cにおいて

  1. 、いくつかのマルチバイトサポート機能(_mbscat、_mbscpy、等)があるが、Windowsでは、文字型は、それらの機能のためにはunsigned char *として定義されます。 _mbsの一連の関数が完全なセットではないという事実(例えば、マルチバイト文字列をlongに変換するための_mbstolはありません)を考えると、ランタイム関数のchar *バージョンのいくつかを強制的に使用することになります。これらの関数間の符号付き/符号なし型の違いにより、コンパイラの問題が発生します。誰もそれらを使用していますか?あなたはエラーを回避するために鋳造の大きな山をしていますか?

機能のmbs*家族は私の経験では、使用はほとんどありませんさ。 mbstowcsmbsrtowcs、及びmbsinitを除いて、これらの機能は、C++、STDは標準C.

  1. ない:: stringはイテレータを有しているが、これらはCHAR_TYPEではなく、コードポイントに基づいています。したがって、私がstd :: string :: iteratorで++を実行した場合、次のコードポイントではなく次のchar_typeを取得します。同様に、std :: string :: operator []を呼び出すと、完全なコードポイントではない可能性のあるchar_typeへの参照が得られます。だから、コードポイントでstd :: stringをどのように反復するのでしょうか? (Cには_mbsinc()関数があります)。

私はmbrtowc(3)はここにマルチバイト文字列の単一のコードポイントをデコードするための最良の選択肢であろうと思います。

全体として、クロスプラットフォームのUnicode互換性のための最良の戦略は、UTF-8のすべてをシングルバイト文字を使用して行うことです。 Windows API関数を呼び出す必要がある場合は、UTF-16に変換し、常に*Wバリアントを呼び出します。ほとんどの非WindowsプラットフォームではUTF-8が既に使用されています。

+0

残念ながら、 'mbrtowc'はWindows上でコードポイントをデコードしません。 –

9

だけで行うUTF-8

サポートライブラリの多くはまた、いくつかはmultiplaftormすぎている、すべてのplaftormでUTF-8のためにあります。 Win32のUTF-16 APIは、すでに述べたように制限があり、一貫性がないため、すべてをUTF-8に保存し、最後にUTF-16に変換する方がよいでしょう。また、Windows APIのための便利なUTF-8ラッピングがあります。

また、アプリケーションレベルのドキュメントでは、UTF-8がますます標準として受け入れられています。すべてのテキスト処理アプリケーションは、UTF-8を受け入れるか、最悪の場合は「ASCIIでいくつかのばかだ」と表示しますが、UTF-16文書をサポートするアプリケーションはわずかですが、そうでないものは「たくさんあります空白の! "

+0

+1ちょうど私がちょうどタイプしていたもの... – Damon

+2

+1、utf8everywhere.orgの考え方をサポートするため –

+1

私は非常に良いリファレンスを追加します。なぜUTF-8をどこに使うべきかhttp://utf8everywhere.org/ –