15


7

C ++のstd :: wstring、UTF-16、UTF-8、およびWindows GUIでの文字列の表示について混乱
私は「常にstd

wstringを使用する」と言われたWindows向けの英語のみのC ++プログラムに取り組んでいますが、チームの誰もそれ以上のことを本当に理解していないようです。

https://stackoverflow.com/questions/402283/stdwstring-vs-stdstring["std::wstring VS std

string]というタイトルの質問をすでに読んでいます。 これは非常に役に立ちましたが、その情報をすべて自分の問題に適用する方法がまだよくわかりません。

私が取り組んでいるプログラムは、Windows GUIにデータを表示します。 そのデータはXMLとして保持されます。 多くの場合、XSLTを使用してそのXMLをレポート目的でHTMLまたはXSL:FOに変換します。

私が読んだことに基づいた私の気持ちは、HTMLはUTF-8としてエンコードされるべきだということです。 私はGUI開発についてほとんど知りませんが、私が読んだ少しの情報は、GUIのすべてがUTF-16エンコードされた文字列に基づいていることを示しています。

これがどこに私を残すかを理解しようとしています。 永続データはすべてUTF-8でエンコードされたXMLであると判断したとします。 これは、UIコンポーネントに永続化されたデータを表示するために、何らかの明示的なUTF-8からUTF-16へのトランスコーディングプロセスを実際に実行する必要があることを意味しますか?

私の説明では説明を使用できると思うので、質問があればそれを提供しようとします。

5 Answer


7


NT4以降のWindowsは、Unicodeでエンコードされた文字列に基づいています、はい。 初期のバージョンはUCS-2に基づいていました。UCS-2は先行バージョンまたはUTF-16であるため、UTF-16がサポートするすべての文字をサポートしていません。 それ以降のバージョンはUTF-16に基づいています。 ただし、すべてのOSがUTF-16 / UCS-2に基づいているわけではありません。 *たとえば、nixシステムは代わりにUTF-8に基づいています。

データを永続的に保存するには、UTF-8が非常に適しています。 これは、すべてのUnicode環境で広くサポートされているエンコードであり、データサイズと損失のないデータ互換性のバランスが取れています。

はい、XMLを解析し、XMLから必要な情報を抽出し、それをデコードしてUIが使用できるものに変換する必要があります。


5


WindowsでC ++でstd

wstringを使用し、ファイルにUTF-8を使用して保存する場合(これは妥当で妥当と思われます)、ファイルへの書き込み時にデータをUTF-8に変換してから、ファイルから読み取るときのUTF-16。 このリンクをチェックしてください:http://mariusbancila.ro/blog/2008/10/20/writing-utf-8-files-in-c/[C++でのUTF-8ファイルの作成]。

Visual Studioのデフォルトのプロジェクト→プロパティ→構成プロパティ→一般→文字セット→ Unicode文字セットを使用し、wchar_tタイプを使用します(つまり、 std

wstring)および_not_では、TCHAR型を使用します。 (例えば。 strlenと_not_ _tcslenのwcslenバージョンを使用します。)


4


std

wstringは技術的にUCS-2です。各文字に2バイトが使用され、コードテーブルは_mostly_ Unicode形式にマップされます。 * UCS-2はUTF-16と同じではないことを理解することが重要です!* UTF-16では、2バイトの範囲外の文字を表すために「サロゲートペア」を使用できますが、UCS-2は正確に2バイトを使用します各文字、ピリオド。

状況に最適なルールは、ディスクの読み取りおよび書き込み時にトランスコーディングを行うことです。 メモリに保存したら、UCS-2形式のままにします。 Windows APIは、UTF-16であるかのように読み取ります(つまり、std

wstringは、サロゲートペアの概念を理解しません。手動で作成すると(唯一の言語が英語)、Windowsはそれらを読みます)。

現代では、シリアル化形式(XMLなど)でデータを読み込んだり、読み込んだりするたびに、おそらくトランスコーディングを行う必要があります。 これは不快で非常に不幸な事実ですが、Unicodeは可変幅の文字エンコーディングであり、C ++でのほとんどの文字ベースの操作は配列として行われるため、一定の間隔が必要です。


3


GUI関連の文字列にWindowsでstd

wstringを使用する利点の1つは、内部的にすべてのWindows API呼び出しがUTF-16を使用して動作することです。 文字列引数を取るすべてのWin32 API呼び出しには2つのバージョンがあることに気づいたことがあります。 たとえば、「MessageBoxA」および「MessageBoxW」。 両方の定義がに存在し、実際にはどちらでも呼び出すことができますが、Unicodeサポートが有効になっている場合、次のようになります。

#define MessageBox MessageBoxW

次に、TCHARやその他のMicrosoftのトリックに取り組み、ANSIとUnicodeの両方のバージョンを持つAPIを簡単に処理できるようにします。 要するに、どちらかを呼び出すことができますが、内部ではUnicodeベースのWindowsカーネルを使用しているため、ワイド文字バージョンを使用しない場合、Win32 API呼び出しを受け入れる各文字列に対してUnicodeに変換するコストがかかります。


1


データに英語しか含まれていないと言っても、おそらく間違いです。 現在、私たちはグローバルな世界にいるので、名前/住所などには外国人のキャラクターがいます。 OK、あなたが持っているデータの種類はわかりませんが、一般的には、データの保存とユーザーへのデータの表示の両方でUNICODEをサポートするアプリケーションを構築すると言えます。 これは、GUIを実行するときに、Windows呼び出しの格納およびUNICODEバージョンにUTF-8でXMLを使用することを推奨します。 また、Windows GUIは各トークンが16ビットであるUTF-16を使用しているため、アプリケーションにデータを16ビット幅の文字列で保存することをお勧めします。 そして、あなたのWindows用のコンパイラはちょうどこの目的のために16ビットとしてstd

wstringを持っていると思います。

そのため、UTF-16とUTF-8の間で多くの変換を行う必要があります。 たとえば、http://en.wikipedia.org/wiki/International_Components_for_Unicode [ICU]のような既存のライブラリを使用してください。