C++ソースコードの標準エンコーディングは何ですか? C++標準はこれについて何かを言っていますか? UnicodeでC++ソースを記述できますか?
たとえば、中国語の文字などの非ASCII文字をコメントに使用できますか?もしそうなら、完全なユニコードまたはユニコードのサブセットのみが許可されていますか? (たとえば、その16ビットの最初のページまたはそれが呼び出されたもの。)
さらに、文字列にUnicodeを使用できますか?例えば:
Wstring str=L"Strange chars: â Țđ ě €€";
C++でのエンコードはかなり複雑です。これが私の理解です。
すべての実装は、基本ソース文字セットの文字をサポートする必要があります。これらには、§2.2/ 1(C++ 11の§2.3/ 1)にリストされている一般的な文字が含まれます。これらの文字はすべて1つのchar
に収まる必要があります。さらに、実装はuniversal-character-names
と呼ばれる方法を使用して他の文字に名前を付ける方法をサポートする必要があり、\uffff
または\Uffffffff
のように見え、Unicode文字を参照するために使用できます。それらのサブセットは、識別子で使用できます(付録Eにリストされています)。
これはすべて素晴らしいことですが、ファイル内の文字からソース文字(コンパイル時に使用)へのマッピングは実装定義です。これは使用されるエンコーディングを構成します。文字通りの意味です(C++ 98バージョン):
必要に応じて、物理ソースファイルの文字は、実装定義の方法で、基本ソース文字セット(行末インジケーターの改行文字の導入)にマッピングされます。トライグラフシーケンス(2.3)は、対応する単一文字の内部表現に置き換えられます。基本ソース文字セット(2.2)にないソースファイル文字は、その文字を指定するuniversal-character-nameに置き換えられます。 (実装は、ソースファイルで実際の拡張文字に遭遇し、ソースファイルでユニバーサル文字名として表現される(つまり、\ uXXXX表記を使用する)同じ拡張文字が処理される限り、任意の内部エンコーディングを使用できます。同様に。)
Gccの場合、オプション-finput-charset=charset
を使用して変更できます。さらに、実行時に値を再設定するために使用される実行文字を変更できます。このための適切なオプションは、charの-fexec-charset=charset
(デフォルトはutf-8
)および-fwide-exec-charset=charset
(デフォルトはutf-16
またはutf-32
のサイズに応じて)です。 wchar_t
)。
私の知る限り、C++標準ではソースコードファイルのエンコードについては何も言及されていません。
通常のエンコーディングは(または以前は)7ビットASCII-一部のコンパイラ(Borlandなど)は、ASCIIコンパイラーとエディターがそれらを受け入れれば、Unicode文字を使用できないという技術的な理由はありません。最新のLinuxベースのツール、およびより優れたWindowsベースのエディターの多くは、UTF-8エンコードを問題ですが、Microsoftのコンパイラがそうなるかどうかはわかりません。
編集:MicrosoftのコンパイラはUnicodeエンコードされたファイルを受け入れるようですが、8ビットASCIIも:
warning C4819: The file contains a character that cannot be represented
in the current code page (932). Save the file in Unicode format to prevent
data loss.
Litbの投稿に加えて、MSVC++はUnicodeもサポートしています。私はそれがBOMからUnicodeエンコーディングを取得することを理解しています。 int (*♫)();
やconst std::set<int> ∅;
のようなコードを確実にサポートします。本当にコードの難読化に興味があるなら:
typedef void ‼; // Also known as \u203C
class ooɟ {
operator ‼() {}
};
ここには2つの問題があります。 1つ目は、変数名など、C++コード(およびコメント)で許可される文字です。 2番目は、文字列および文字列リテラルで許可される文字です。
前述のように、C++コンパイラmustは、コードおよびコメントで許可されている文字に対して、非常に制限されたASCIIベースの文字セットをサポートします。実際には、この文字セットは一部のヨーロッパの文字セット(および特に角かっこなどのいくつかの文字を持たない一部のヨーロッパのキーボード)ではうまく機能しなかったため、有向グラフと三文字グラフの概念は導入されました。現在、多くのコンパイラはこの文字セット以上を受け入れますが、保証はありません。
文字列と文字列リテラルに関して、C++にはワイド文字とワイド文字列の概念があります。ただし、その文字セットのエンコーディングは未定義です。実際には、ほとんど常にユニコードですが、ここで保証があるとは思いません。ワイド文字の文字列リテラルはL "文字列リテラル"のように見え、これらはstd :: wstringに割り当てることができます。
C++ 11は、UTF-8、UTF-16ビッグエンディアン、UTF-16リトルエンディアン、UTF-32ビッグエンディアン、UTF-32リトルエンディアンとしてエンコードされたUnicode文字列と文字列リテラルの明示的なサポートを追加しました。
文字列のエンコードには、\表記を使用することを意図していると思います。例:
std::wstring str = L"\u20AC"; // Euro character
このコンテキストで、MSVC++警告C4819が表示された場合、ソースファイルのコーディングを「UTF-8 with Bom」に変更するだけです。
GCC 4.1はこれをサポートしませんが、GCC 4.4はサポートし、最新のQtバージョンはGCC 4.4を使用するため、ソースファイルのコーディングとして「UTF-8 with Bom」を使用します。
C++のワイド文字は、実際にはUnicode文字列ではないことにも注意してください。それらは、通常は16文字ですが、時には32ビットの大きな文字列です。これは実装定義ですが、IIRCでは8ビットwchar_t
を使用できます。エンコードの実際の保証はないため、テキスト処理などを行う場合は、おそらくtypedefをUnicodeエンティティに最適な整数型に変更します。
C++ 1xには、UTF-8エンコード文字列リテラル(u8"text"
)、UTF-16およびUTF-32データ型(char16_t
およびchar32_t
IIRC)の形式で追加のUnicodeサポートがあります。および対応する文字列定数(u"text"
およびU"text"
)。ただし、\uxxxx
または\Uxxxxxxxx
定数なしで指定された文字のエンコードは実装定義のままです(リテラル以外の複雑な文字列型のエンコードはサポートされていません)
私の知る限り、ワイド文字列にはあらゆるタイプの文字を入れることができるため、標準化されていません。コンパイラが正しく動作するようにするには、コンパイラがUnicodeソースコードに設定されていることを確認するだけです。