2012-11-18 7 views
14

Wikipediaから必要リテラルU8列である:はC++ 11

C++コンパイラでのUnicodeのサポートを向上させる目的で、char型の定義は、少なくともサイズであるように改変されていますUTF-8の8ビット符号化を格納するために必要である。

私はポータブルアプリケーションを作成するためにこれが何を意味するのだろうかと思います。これを書くことに違いがありますか?

const char[] str = "Test String"; 

またはこれは何ですか?

const char[] str = u8"Test String"; 

コード内のすべての文字列リテラルに後者を使用しない理由はありますか?

TestStringの中に非ASCII文字があるとどうなりますか?

+1

http://stackoverflow.com/questions/9739070/char-encodingは、文字列の便利 – Yakk

+7

一つはUTF-8であることがあり、他の一つはEBCDICのようなものである可能性があります。 –

+0

多分、エンコード関連の質問があります。[#1](http://stackoverflow.com/questions/6300804/wchars-encodings-standards-and-portability)、[#2](http: /stackoverflow.com/questions/6796157/unicode-encoding-for-string-literals-in-c0x)、[#3](http://stackoverflow.com/questions/7562609/what-does-cuchar-provide-and) –

答えて

18

"Test String"のエンコーディングは、実装定義のシステムエンコーディング(狭い、おそらくマルチバイトのエンコーディング)です。

u8"Test String"のエンコーディングは、常にUTF-8です。

この例では大したことはありません。文字列にUnicodeのリテラル(\U0010FFFFなど)を含めると、それらは(UTF-8でエンコードされた)ものを得ることができますが、システムエンコードされた文字列で表現できるかどうか、実装定義されています。

役立つ場合は、EBCDICマシンでソースコードをオーサリングしているとします。その後、リテラル "Test String"はソースファイル自体に常にEBCDICエンコードされますが、u8初期化配列にはUTF-8エンコード値が含まれますが、最初の配列にはEBCDICエンコード値が含まれます。

4

コンパイラは、プラットフォームに固有のネイティブエンコーディングを選択します。典型的なPOSIXシステムでは、おそらくASCIIと、ASCII範囲外の文字値に対する環境の設定に依存するものを選ぶでしょう。メインフレームではおそらくEBCDICを選択します。ファイルやコマンドラインなどから受け取った文字列を比較することは、おそらくネイティブキャラクタセットで最も効果的です。しかし、UTF-8を使用して明示的にエンコードされたファイルを処理する場合は、おそらくu8"..."文字列を使用するのが最良です。つまり、文字エンコーディングに関する最近の変更では、CおよびC++での文字列処理の基本的な前提が壊れています。つまり、各文字オブジェクト(charwchar_tなど)が1文字を表すために使用されました。これは、UTF-8文字列の場合、それぞれの文字オブジェクトがちょうど何らかの文字のバイトを表していることを意味しています。その結果、すべての文字列操作、文字分類などの機能は必ずしもこれらの文字列で機能するとは限りません。このような文字列を標準に含めるために並んでいるライブラリはありません。

+0

charはおそらくマルチバイトであることが知られています(つまり、1文字あたり1つの文字が間違っていると仮定していたプログラマ)。一方、wchar_tには固定幅が必要です。残念ながら、Unicodeは根本的に、固定幅とは何かを前提にしています。 – bames53

+0

私は、文字列がマルチバイトエンコーディングを保持するためにかなり長い間使用されているが、標準ではこの事実を認めず、内部文字を1単位として扱ったという事実に必ずしも同意していない。すべての標準的なファシリティ処理文字列は、文字が単なる1つの単位であるかのように動作します。例えば、部分文字列の開始と終了がUnicode文字の途中にある場合、 's.substr(b、n)'を持つのは実際にはあまり意味がありません。 'wchar_t'文字列でさえ、例えば文字を結合するような固定幅の文字を持っています。 –

+0

@DietmarKühl: "標準はこの事実を認めなかった"、私はあなたがライブラリ関数*を意味すると思う。 C++標準自体は、マルチバイト(文字単位)文字列の存在を常に認識しています。たとえば、Windowsの規約が失敗したMBCSesや、既存の習慣を適切に標準化できなかったところでは、それが推奨されています(私は正確には何も思い出していません)。 –

13

あなたがウィキペディア引用:C++コンパイラでのUnicodeのサポートを向上させる目的で

、char型の定義は、8ビットのコーディングを格納するために必要な最低のサイズに変更されましたUTF-8。

まあ、 ”の目的のために。 charは、C標準でcharに必要な範囲のために、常に少なくとも8ビット、つまりCHAR_BITが≥ 8であることが保証されています。 C++標準には”が組み込まれています(引用C++ 11§17.5.1.5/ 1)“です。

目的の変更については、とすれば、C標準への依存を知らない読者のためのものを明確にするだけです。

u8リテラルプレフィックスの効果に関しては、それ

  • は、実行可能ファイルに文字列のエンコーディングに影響しますが、

  • が、残念ながらそれの種類には影響を与えません。

したがって、どちらの場合も"tørrfisk"u8"tørrfisk"あなたはchar const[n]を取得します。しかし、以前のリテラルでは、エンコーディングはコンパイラのために選択されたものである。後者のリテラルでは、UTF-8であることが保証されていますが、“ø”でエンコードされることになります。この場合、エンコードされる文字数は8バイトで、ラテン1(またはWindows ANSI Western)です。わずかに大きい配列サイズの場合、2または3バイト(正確にはリコールできません)。

0

実行文字は、コンパイラのを設定した場合は、UTF-8に設定されているコンパイラは両方のケースではUTF-8に文字を変換するのでu8は、使用されているかどうか、それは違いはありません。

コンパイラ実行文字セットがシステムの非UTF8コードページ(たとえばVisual C++のデフォルト)である場合、u8を省略すると、非ASCII文字が正しく処理されないことがあります。たとえば、ワイド文字列への変換はクラッシュします。 VS15で:

std::string narrowJapanese("スタークラフト"); 
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convertWindows; 
std::wstring wide = convertWindows.from_bytes(narrowJapanese); // Unhandled C++ exception in xlocbuf.