15

文字列リテラルの前にそれぞれ//を付けることにより、C++11でUTF-8 / 16 u8/ 32文字列リテラルを記述できます。コンパイラは、これらの新しいタイプの文字列リテラル内に非ASCII文字を含むUTF-8ファイルをどのように解釈する必要がありますか?標準ではファイルエンコーディングが指定されていないことを理解しています。その事実だけでは、ソースコード内の非ASCII文字の解釈が完全に未定義の動作になり、機能の有用性が少し低下します。uU

で単一のUnicode文字をエスケープできることは理解していますが\uNNNN、たとえば、通常は複数のUnicode文字を含む完全なロシア語またはフランス語の文ではあまり読みやすくありません。

さまざまな情報源から私が理解していることは、現在のWindows実装やLinux実装などuと同等になるはずだということです。それを念頭に置いて、古い文字列リテラル修飾子に必要な動作は何であるかについても疑問に思っています...LU

コードサンプルサルの場合:

string utf8string a = u8"L'hôtel de ville doit être là-bas. Ça c'est un fait!";
string utf16string b = u"L'hôtel de ville doit être là-bas. Ça c'est un fait!";
string utf32string c = U"L'hôtel de ville doit être là-bas. Ça c'est un fait!";

理想的な世界では、これらの文字列はすべて同じコンテンツを生成します(変換後の文字のように)が、C ++での私の経験から、これは最も確実に実装定義されており、おそらく最初のものだけが私が望むことを実行することがわかりました。

4

3 に答える 3

9

GCCでは、以下を使用します-finput-charset=charset

入力ファイルの文字セットからGCCで使用されるソース文字セットへの変換に使用される入力文字セットを設定します。ロケールで指定されていない場合、またはGCCがロケールからこの情報を取得できない場合、デフォルトはUTF-8です。これは、ロケールまたはこのコマンドラインオプションのいずれかで上書きできます。現在、競合がある場合はコマンドラインオプションが優先されます。charsetは、システムの「iconv」ライブラリルーチンでサポートされている任意のエンコーディングにすることができます。

-fexec-charsetオプションともチェックしてください-fwide-exec-charset

最後に、文字列リテラルについて:

char     a[] = "Hello";
wchar_t  b[] = L"Hello";
char16_t c[] = u"Hello";
char32_t d[] = U"Hello";

文字列リテラルのサイズ修飾子(、、L)はu、リテラルのタイプUを決定するだけです。

于 2011-07-22T18:45:51.013 に答える
7

コンパイラは、これらの新しいタイプの文字列リテラル内に非ASCII文字を含むUTF-8ファイルをどのように解釈する必要がありますか。標準ではファイルエンコーディングが指定されていないことを理解しています。その事実だけでは、ソースコード内の非ASCII文字の解釈が完全に未定義の動作になり、機能の有用性が少し低下します。

n3290から、2.2翻訳フェーズ[lex.phases]

物理ソースファイルの文字は、必要に応じて、実装で定義された方法で、基本的なソース文字セット(行末インジケーターに改行文字を導入)にマップされます。受け入れられる物理ソースファイル文字のセットは、実装によって定義されます。[ここに三重音字について少し説明します。]基本ソース文字セット(2.3)にないソースファイル文字は、その文字を指定するユニバーサル文字名に置き換えられます。(実装では、ソースファイルで実際に検出された拡張文字、およびソースファイルでユニバーサル文字名として(つまり、\ uXXXX表記を使用して)表現された同じ拡張文字である限り、任意の内部エンコーディングを使用できます。この置換が生の文字列リテラルで元に戻される場合を除いて、同等に処理されます。)

実装がエンコーディングをどのように扱うかを説明するために使用されている多くの標準用語があります。これが、何が起こるかについての、いくらか単純で段階的な説明としての私の試みです。

物理ソースファイルの文字は、実装で定義された方法で、基本的なソース文字セットにマップされます[...]

ファイルエンコーディングの問題は手作業で行われます。標準は基本的なソース文字セットのみを考慮し、実装がそこに到達する余地を残します。

基本ソース文字セット(2.3)に含まれていないソース・ファイル文字は、その文字を指定するユニバーサル文字名に置き換えられます。

基本的なソースセットは、許可される文字の単純なリストです。ASCIIではありません(詳細を参照)。このリストにないものはすべて、(少なくとも概念的には)フォームに「変換」され\uXXXXます。

したがって、使用されるリテラルまたはファイルエンコーディングの種類に関係なく、ソースコードは概念的に基本的な文字セット+一連の。に変換され\uXXXXます。概念的に言うと、実装が実際に行うことは通常は単純であるためです。たとえば、Unicodeを直接処理できるためです。重要な部分は、標準が拡張文字と呼ぶもの(つまり、基本ソースセットからではない)は、使用時に同等の\uXXXX形式と区別できないようにする必要があるということです。C ++ 03はEBCDICプラットフォームなどで使用できるため、ASCIIに関する推論には最初から欠陥があることに注意してください。

最後に、私が説明したプロセスは、(生ではない)文字列リテラルにも起こります。つまり、コードは次のように記述した場合と同等です。

string utf8string a = u8"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";
string utf16string b = u"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";
string utf32string c = U"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";
于 2011-07-22T20:24:39.583 に答える
0

原則として、エンコーディングの問題は、文字列を人間に見えるようにして出力する場合にのみ重要です。これは、プログラミング言語の定義がコーディング計算のみを扱うため、プログラミング言語の定義方法の問題ではありません。したがって、エディタに表示されるものが出力に表示されるものと同じになるかどうかを決定するときは(画面上またはPDFのいずれの種類の画像でも)、どの規則を使用するかを自問する必要があります。ユーザーインタラクションライブラリとオペレーティングシステムがコーディングされた方法を想定しています。(たとえば、Qt5に関するこの種の情報は次のとおりです。:Qt5では、別の設定をオンにしない限り、QStringの旧式の文字列リテラルの内容がソースファイルでutf8としてエンコードされている場合、アプリケーションのユーザーとして表示されるものとプログラマーとして表示されるものは一致します。アプリケーションの実行中に)。

結論として、Kerrek SBは正しく、Damonは間違っていると思います。実際、コードでリテラルを指定する方法では、ソースファイルでコンテンツを入力するために使用されるエンコーディングではなく、そのタイプを指定する必要があります。リテラルのタイプは、それに行われる計算に関係するものです。のようなものu"string"は、単なる「Unicodeコードユニット」の配列(つまり、タイプの値)です。char16_t)、オペレーティングシステムまたは他のサービスソフトウェアが後でそれらに行うものは何でも、しかし彼らの仕事はあなたまたは別のユーザーを探します。計算中の数値の「意味」(つまり、Unicodeのコードを表す)と、テキストエディタで作業するときの画面での数値との間に対応する、別の規則を自分で追加するという問題が発生します。 。プログラマーとしてのあなたがその「意味」をどのように使用するか、そしてどのようにこの他の対応を強制できるかは、当然、実装によって定義されます。これは、コーディング計算とは関係がなく、ツールの使用の快適さだけに関係するためです。 。

于 2015-10-10T15:02:43.800 に答える