61

C++ ソース コードの標準エンコーディングは何ですか? C++標準はこれについて何か言っていますか? C++ ソースを Unicode で記述できますか?

たとえば、コメントに漢字などの非 ASCII 文字を使用できますか? もしそうなら、完全な Unicode は許可されていますか、それとも Unicode のサブセットだけですか? (たとえば、その 16 ビットの最初のページまたはそれが呼ばれるもの。)

さらに、文字列に Unicode を使用できますか? 例えば:

Wstring str=L"Strange chars: â Țđ ě €€";
4

8 に答える 8

37

C++でのエンコードはかなり複雑です。これが私の理解です。

すべての実装は、基本的なソース文字セットの文字をサポートする必要があります。これらには、§2.2/ 1(C ++11では§2.3/1)にリストされている一般的な文字が含まれます。これらの文字はすべて1つに収まる必要がありますchar。さらに、実装は、またはのuniversal-character-namesように見える方法を使用して他の文字に名前を付ける方法をサポートする必要があり、Unicode文字を参照するために使用できます。それらのサブセットは識別子で使用できます(付録Eにリストされています)。\uffff\Uffffffff

これはすべて素晴らしいことですが、ファイル内の文字からソース文字(コンパイル時に使用される)へのマッピングは実装で定義されています。これは、使用されるエンコーディングを構成します。文字通りの内容は次のとおりです(C ++ 98バージョン)。

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

gccの場合、オプションを使用して変更できます-finput-charset=charset。さらに、実行時に値を再プリセットするために使用される実行文字を変更できます。このための適切なオプションは-fexec-charset=charset、char(デフォルトはutf-8)および-fwide-exec-charset=charset(デフォルトは、utf-16またはutf-32のサイズに応じてwchar_t)です。

于 2008-12-01T19:38:42.700 に答える
11

私が知る限り、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.
于 2008-12-01T18:26:21.443 に答える
10

litb の投稿に加えて、MSVC++ は Unicode もサポートしています。BOM から Unicode エンコーディングを取得することを理解しています。 コードの難読化に本当に興味がある場合はint (*♫)();、次のようなコードを確実にサポートします。const std::set<int> ∅;

typedef void ‼; // Also known as \u203C
class ooɟ {
    operator ‼() {}
};
于 2008-12-03T15:03:03.270 に答える
6

ここには 2 つの問題があります。1 つ目は、変数名など、C++ コード (およびコメント) で使用できる文字です。2 つ目は、文字列と文字列リテラルで使用できる文字です。

前述のように、C++ コンパイラは、コードおよびコメントで使用できる文字について、非常に制限された ASCII ベースの文字セットをサポートする必要があります。実際には、この文字セットは一部のヨーロッパの文字セット (特に角括弧などの文字が少ない一部のヨーロッパのキーボード) ではうまく機能しなかったため、ダイグラフとトリグラフの概念が使用されました。紹介された。現時点では、多くのコンパイラがこの文字セット以外を受け入れますが、保証はありません。

文字列と文字列リテラルに関しては、C++ にはワイド文字とワイド文字列の概念があります。ただし、その文字セットのエンコーディングは定義されていません。実際にはほとんどの場合 Unicode ですが、保証はないと思います。ワイド文字列リテラルは L"stringliteral" のように見え、std::wstring に割り当てることができます。


C++11 では、UTF-8、UTF-16 ビッグ エンディアン、UTF-16 リトル エンディアン、UTF-32 ビッグ エンディアン、UTF-32 リトル エンディアンとしてエンコードされた Unicode 文字列と文字列リテラルの明示的なサポートが追加されました。

于 2008-12-02T00:14:49.227 に答える
5

文字列にエンコードするには、 \u表記を使用することを意図していると思います。

std::wstring str = L"\u20AC"; // Euro character
于 2008-12-01T18:26:42.130 に答える
3

また、C++ のワイド文字は実際には Unicode 文字列ではないことにも注意してください。通常は 16 ビットですが、32 ビットの場合もあります。ただし、これは実装定義ですが、IIRC は 8 ビットを持つことができますwchar_tそれらのエンコーディングに関して実際の保証はありません。整数型を Unicode エンティティに追加します。

C++1x には、UTF-8 エンコーディング文字列リテラル ( u8"text")、UTF-16 および UTF-32 データ型 (char16_tおよびchar32_tIIRC)、対応する文字列定数 (u"text"およびU"text") の形式で追加の Unicode サポートがあります。\uxxxxただし、または\Uxxxxxxxx定数なしで指定された文字のエンコーディングは実装定義のままです (また、リテラル外の複雑な文字列型のエンコーディング サポートはありません)。

于 2008-12-01T19:51:50.647 に答える
2

このコンテキストで、MSVC++ 警告 C4819 が表示された場合は、ソース ファイルのコーディングを "UTF-8 with Bom" に変更してください。

GCC 4.1 はこれをサポートしていませんが、GCC 4.4 はサポートしており、最新の Qt バージョンは GCC 4.4 を使用しているため、ソース ファイルのコーディングとして "UTF-8 with Bom" を使用してください。

于 2012-08-23T03:10:58.187 に答える
0

私の知る限り、ワイド文字列には任意のタイプの文字を入れることができるため、標準化されていません。正しく動作させるには、コンパイラが Unicode ソース コードに設定されていることを確認する必要があります。

于 2008-12-01T18:27:16.683 に答える