文字列リテラルと文字リテラル (C++)

C++ はさまざまな文字列と文字型をサポートし、これらの型のリテラル値を表す方法を提供しています。 ソース コードでは、文字セットを使用して文字リテラルと文字列リテラルの内容を表現します。 ユニバーサル文字名とエスケープ文字を使用すると、基本ソース文字セットのみを使用してあらゆる文字列を表現できます。 未加工文字列リテラルを使用すると、エスケープ文字の使用を避けられるとともに、全種類の文字列リテラルを表すことができます。 余分な構築または変換手順を実行することなく、std::string リテラルを作成することもできます。

#include <string>
using namespace std::string_literals; // enables s-suffix for std::string literals

int main()
{
    // Character literals
    auto c0 =   'A'; // char
    auto c1 = u8'A'; // char
    auto c2 =  L'A'; // wchar_t
    auto c3 =  u'A'; // char16_t
    auto c4 =  U'A'; // char32_t

    // Multicharacter literals
    auto m0 = 'abcd'; // int, value 0x61626364

    // String literals
    auto s0 =   "hello"; // const char*
    auto s1 = u8"hello"; // const char* before C++20, encoded as UTF-8,
                         // const char8_t* in C++20
    auto s2 =  L"hello"; // const wchar_t*
    auto s3 =  u"hello"; // const char16_t*, encoded as UTF-16
    auto s4 =  U"hello"; // const char32_t*, encoded as UTF-32

    // Raw string literals containing unescaped \ and "
    auto R0 =   R"("Hello \ world")"; // const char*
    auto R1 = u8R"("Hello \ world")"; // const char* before C++20, encoded as UTF-8,
                                      // const char8_t* in C++20
    auto R2 =  LR"("Hello \ world")"; // const wchar_t*
    auto R3 =  uR"("Hello \ world")"; // const char16_t*, encoded as UTF-16
    auto R4 =  UR"("Hello \ world")"; // const char32_t*, encoded as UTF-32

    // Combining string literals with standard s-suffix
    auto S0 =   "hello"s; // std::string
    auto S1 = u8"hello"s; // std::string before C++20, std::u8string in C++20
    auto S2 =  L"hello"s; // std::wstring
    auto S3 =  u"hello"s; // std::u16string
    auto S4 =  U"hello"s; // std::u32string

    // Combining raw string literals with standard s-suffix
    auto S5 =   R"("Hello \ world")"s; // std::string from a raw const char*
    auto S6 = u8R"("Hello \ world")"s; // std::string from a raw const char* before C++20, encoded as UTF-8,
                                       // std::u8string in C++20
    auto S7 =  LR"("Hello \ world")"s; // std::wstring from a raw const wchar_t*
    auto S8 =  uR"("Hello \ world")"s; // std::u16string from a raw const char16_t*, encoded as UTF-16
    auto S9 =  UR"("Hello \ world")"s; // std::u32string from a raw const char32_t*, encoded as UTF-32
}

文字列リテラルは、プレフィックスを省略することも、u8Lu、または U プレフィックスを使用することもできます。これらは、それぞれ、ナロー文字 (単一バイトまたは複数バイト)、UTF-8、ワイド文字 (UCS-2 または UTF-16)、UTF-16、UTF-32 エンコードを表します。 未加工文字列リテラルは、上記のエンコーディングの未加工バージョンとして Ru8RLRuRUR プレフィックスを使用できます。 一時的なまたは静的な std::string の値を作成するには、文字列リテラルまたは未加工文字列リテラルを s サフィックスと一緒に使用できます。 詳細については、後述する「文字列リテラル」を参照してください。 基本ソース文字セット、ユニバーサル文字名、ソース コードでの拡張コードページからの文字の使用についての詳細は、「文字セット」を参照してください。

文字リテラル

文字リテラル は、定数文字で構成されます。 これは単一引用符で囲んだ文字によって表されます。 文字リテラルには次の 4 種類があります:

  • char 型の通常文字リテラル。たとえば 'a'

  • char 型の UTF-8 文字リテラル (C++20 では char8_t)。たとえば u8'a'

  • wchar_t型のワイド文字リテラル。たとえば L'a'

  • char16_t 型の UTF-16 文字リテラル。たとえば u'a'

  • char32_t 型の UTF-32 文字リテラル。たとえば U'a'

文字リテラルに使用する文字には、任意の文字を含めることができます。ただし、円記号 (\)、単一引用符 (')、改行の予約文字は除きます。 予約文字は、エスケープ シーケンスを使用して指定することができます。 型が文字を保持するのに十分な大きさであれば、文字はユニバーサル文字名を使用して指定することができます。

[エンコード]

文字リテラルは、プレフィックスに基づいて異なる方法でエンコードされます。

  • プレフィックスのない文字リテラルは、通常の文字リテラルです。 実行文字セットで表すことができる単一の文字、エスケープ シーケンス、またはユニバーサル文字名を含む通常の文字リテラルの値には、実行文字セットにおけるそのエンコードの数値と同じ値が設定されています。 複数の文字、エスケープ シーケンス、またはユニバーサル文字名を含む通常の文字リテラルは、多文字リテラルです。 実行文字セットで表現できない多文字リテラルまたは通常の文字リテラルには型 int があり、その値は実装定義されています。 MSVC については、以下のMicrosoft 固有の項を参照してください。

  • L プレフィックスで始まる文字リテラルは、ワイド文字リテラルです。 1 つの文字、エスケープ シーケンス、またはユニバーサル文字名を含むワイド文字リテラルの値には、実行ワイド文字セット内で文字リテラルが表現されていない場合、実行ワイド文字セットのエンコードの数値と同じ値が含まれます。この場合、値は実装定義になります。 複数の文字、エスケープ シーケンス、またはユニバーサル文字名を含むワイド文字リテラルの値は、実装によって定義されます。 MSVC については、以下のMicrosoft 固有の項を参照してください。

  • u8 プレフィックスで始まる文字リテラルは、UTF-8 文字リテラルです。 1 文字、エスケープシーケンス、またはユニバーサル文字名を含む UTF-8 文字リテラルの値は、1 つの UTF-8 コード単位 (C0 コントロールと基本ラテン Unicode ブロックに対応する) で表すことができる場合は、ISO 10646 コード ポイント値と同じ値になります。 値を 1 つの UTF-8 コード単位で表すことができない場合、プログラムの形式が正しくありません。 複数の文字、エスケープ シーケンス、またはユニバーサル文字名を含む UTF-8 文字リテラルの形式が正しくありません。

  • u プレフィックスで始まる文字リテラルは、UTF-16 文字リテラルです。 1 つの文字、エスケープ シーケンス、またはユニバーサル文字名を含む UTF-16 文字リテラルの値は、1 つの UTF-16 コード単位 (基本的な多言語面に対応) で表すことができる場合は、ISO 10646 のコード ポイント値と同じ値になります。 値を 1 つの UTF-16 コード単位で表すことができない場合、プログラムの形式が正しくありません。 複数の文字、エスケープ シーケンス、またはユニバーサル文字名を含む UTF-16 文字リテラルの形式が正しくありません。

  • U プレフィックスで始まる文字リテラルは、UTF-32 文字リテラルです。 1 つの文字、エスケープ シーケンス、またはユニバーサル文字名を含む 32 UTF-8 文字リテラルの値には、ISO 10646 のコード ポイント値と同じ値が指定されています。 複数の文字、エスケープ シーケンス、またはユニバーサル文字名を含む UTF-32 文字リテラルの形式が正しくありません。

エスケープ シーケンス

エスケープ シーケンスには、単純、8 進数、16 進数という 3 つの種類があります。 エスケープ シーケンスとして次の値のいずれかを使用できます。

Value エスケープ シーケンス
改行 \n
バックスラッシュ \\
水平タブ \t
疑問符 ? または\。
垂直タブ \v
単一引用符 \'
バックスペース \b
二重引用符 (") \"
キャリッジ リターン \r
null 文字 \0
フォーム フィード \f
8 進数 \ooo
警告 (ベル) \a
16 進数 \xhhh

8 進数のエスケープ シーケンスは、円記号に続いて 1 ~ 3 桁の 8 進数の数字を並べたものです。 8 進数のエスケープ シーケンスは、3 番目の桁よりも早く検出された場合、8 進数の数字ではない最初の文字で終了します。 有効な 8 進数の最大値は \377 です。

16 進数のエスケープ シーケンスは、円記号の後に文字 x を続け、その後に 1 桁以上の 16 進数を並べたものです。 先行 0 は無視されます。 通常または u8 のプレフィックスが付いた文字リテラルでは、最大の 16 進値は 0xFF です。 L プレフィックス付きまたは u プレフィックス付きワイド文字リテラルでは、最大の 16 進値は 0xFFFF です。 U プレフィックス付きワイド文字リテラルでは、最大の 16 進値は 0xFFFFFFFF です。

このサンプル コードでは、通常の文字リテラルを使用したエスケープ文字の例をいくつか示します。 同じエスケープ シーケンス構文は、他の文字リテラル型に対して有効です。

#include <iostream>
using namespace std;

int main() {
    char newline = '\n';
    char tab = '\t';
    char backspace = '\b';
    char backslash = '\\';
    char nullChar = '\0';

    cout << "Newline character: " << newline << "ending" << endl;
    cout << "Tab character: " << tab << "ending" << endl;
    cout << "Backspace character: " << backspace << "ending" << endl;
    cout << "Backslash character: " << backslash << "ending" << endl;
    cout << "Null character: " << nullChar << "ending" << endl;
}
/* Output:
Newline character:
ending
Tab character:  ending
Backspace character:ending
Backslash character: \ending
Null character:  ending
*/

円記号 (\) は、行の末尾に置かれている場合は行連結文字です。 円記号が文字リテラルとして表示されるようにするには、円記号を 2 つ並べて (\\) 入力する必要があります。 行連結文字について詳しくは、「 Phases of Translation」をご覧ください。

Microsoft 固有の仕様

狭い複数文字リテラルから値を作成するために、コンパイラは、一重引用符で囲まれた文字または文字シーケンスを 32 ビット整数以内の 8 ビット値に変換します。 リテラル内の複数の文字に対応するバイトが、必要に応じて、上位から下位に入力されます。 次に、通常の規則に従って、整数が変換先の型に変換されます。 例えば、char 値を作成する場合、コンパイラは下位バイトを取得します。 wchar_t または char16_t 値を作成する場合、コンパイラは下位ワードを取得します。 割り当てられたバイトまたはワードを上回るビットが設定された場合、コンパイラは結果が切り捨てられることを警告します。

char c0    = 'abcd';    // C4305, C4309, truncates to 'd'
wchar_t w0 = 'abcd';    // C4305, C4309, truncates to '\x6364'
int i0     = 'abcd';    // 0x61626364

見かけ上 4 桁以上を含む 8 進数のエスケープ シーケンスは、3 桁の 8 進数シーケンスの後ろに多文字リテラル文字としての桁が続くものとして扱われます。これは、想定外の結果につながる可能性があります。 次に例を示します。

char c1 = '\100';   // '@'
char c2 = '\1000';  // C4305, C4309, truncates to '0'

8 進数以外の文字が含まれているように見えるエスケープ シーケンスは、最後の 8 進数文字までの 8 進数シーケンスとして評価され、その後に多文字リテラルの後続の文字として残りの文字が続きます。 警告 C4125 は、8 進数以外の最初の文字が 10 進数の場合に生成されます。 次に例を示します。

char c3 = '\009';   // '9'
char c4 = '\089';   // C4305, C4309, truncates to '9'
char c5 = '\qrs';   // C4129, C4305, C4309, truncates to 's'

\377 より大きい値を持つ 8 進数のエスケープ シーケンスは、エラー C2022 の原因となります ('value-in-decimal': 文字に対して大きすぎる)。

見かけ上 16 進数文字と 16 進数以外の文字を含むエスケープ シーケンスは多文字リテラルとして評価されます。これは、最後の 16 進数文字までは 16 進数のエスケープ シーケンスで、その後に 16 進数以外の文字が続く16 進数のエスケープ シーケンスを含みます。 16 進数の数字を含まない 16 進数のエスケープ シーケンスでは、"16 進型リテラルには、少なくとも 1 桁の 16 進数が必要です" という C2153 コンパイラ エラーが発生します。

char c6 = '\x0050'; // 'P'
char c7 = '\x0pqr'; // C4305, C4309, truncates to 'r'

L で始まるワイド文字リテラルに多文字シーケンスが含まれている場合は、最初の文字から値が取得され、コンパイラによって警告 C4066 が生成されます。 同等の通常の多文字リテラルの動作とは異なり、後続の文字は無視されます。

wchar_t w1 = L'\100';   // L'@'
wchar_t w2 = L'\1000';  // C4066 L'@', 0 ignored
wchar_t w3 = L'\009';   // C4066 L'\0', 9 ignored
wchar_t w4 = L'\089';   // C4066 L'\0', 89 ignored
wchar_t w5 = L'\qrs';   // C4129, C4066 L'q' escape, rs ignored
wchar_t w6 = L'\x0050'; // L'P'
wchar_t w7 = L'\x0pqr'; // C4066 L'\0', pqr ignored

Microsoft 固有のセクションはここで終了です。

ユニバーサル文字名

文字リテラルとネイティブ (未加工ではない) 文字列リテラルでは、ユニバーサル文字名であらゆる文字を表すことができます。 ユニバーサル文字名は、プレフィックス \U の後ろに 8 桁の Unicode コード ポイントが続く形式、または、プレフィックス \u の後ろに 4 桁の Unicode コード ポイントが続く形式です。 正しい形式のユニバーサル文字名を作成するには、それぞれ、8 桁または 4 桁のすべてが存在する必要があります。

char u1 = 'A';          // 'A'
char u2 = '\101';       // octal, 'A'
char u3 = '\x41';       // hexadecimal, 'A'
char u4 = '\u0041';     // \u UCN 'A'
char u5 = '\U00000041'; // \U UCN 'A'

サロゲート ペア

ユニバーサル文字名は、サロゲート コード ポイントの範囲 D800 ~ DFFF 内の値をエンコードできません。 Unicode サロゲート ペアの場合は、 \UNNNNNNNNを使用してユニバーサル文字名を指定します。ここで、NNNNNNNN は文字用の 8 桁のコード ポイントです。 コンパイラは、必要に応じて、サロゲート ペアを生成します。

C++03 では、言語では、文字のサブセットをユニバーサル文字名で表すだけで、有効な Unicode 文字を実際に表していない一部のユニバーサル文字名を使用することができました。 この誤りは、C++11 の標準で修正されました。 C++11 では、文字リテラルと文字列リテラルの両方と識別子でユニバーサル文字名を使用できます。 ユニバーサル文字名について詳しくは、「 Character Sets」をご覧ください。 Unicode について詳しくは、「 Unicode」をご覧ください。 サロゲート ペアについて詳しくは、「 サロゲート ペアと補助文字」をご覧ください。

文字列リテラル

文字列リテラルは文字のシーケンスを表し、その全体が、null で終わる文字列を形成します。 文字列は二重引用符で囲む必要があります。 文字列リテラルの種類は次のとおりです。

ナロー文字列リテラル

ナロー文字列リテラルは、プレフィックスがなく、二重引用符で区切られ、null で終わる const char[n] 型の配列です。ここで、n は配列の長さ (バイト数) です。 ナロー文字列リテラルには、二重引用符 (")、円記号 (\)、または改行文字を除く、任意のグラフィック文字を含めることができます。 ナロー文字列リテラルには、上記のエスケープ シーケンスと、1 バイトに収まるユニバーサル文字名を含めることもできます。

const char *narrow = "abcd";

// represents the string: yes\no
const char *escaped = "yes\\no";

UTF-8 でエンコードされた文字列

UTF-8 でエンコードされた文字列は、u8 プレフィックスが付き、二重引用符で区切られ、null で終わる const char[n] 型の配列です。ここで、n はエンコードされた配列の長さ (バイト数) です。 u8 プレフィックス付き文字列リテラルには、二重引用符 (")、円記号 (\)、または改行文字を除く、任意のグラフィック文字を含めることができます。 u8 プレフィックス付き文字列リテラルには、上記のエスケープ シーケンスと、任意のユニバーサル文字名を含めることもできます。

C++ 20 では、ポータブル char8_t (utf-8 でエンコードされた 8 ビット Unicode) 文字型が導入されています。 C++ 20 では、u8 リテラル プレフィックスは、char の代わりに char8_t の文字または文字列を指定します。

// Before C++20
const char* str1 = u8"Hello World";
const char* str2 = u8"\U0001F607 is O:-)";
// C++20 and later
const char8_t* u8str1 = u8"Hello World";
const char8_t* u8str2 = u8"\U0001F607 is O:-)";

ワイド文字列リテラル

ワイド文字列リテラルは、null で終わる定数 wchar_t の配列で、'L' プレフィックスが付いています。さらに、二重引用符 (")、円記号 (\)、または改行文字を除く任意のグラフィック文字を含めることができます。 ワイド文字列リテラルには、上記のエスケープ シーケンスと、任意のユニバーサル文字名を含めることができます。

const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";

char16_t および char32_t (C++11)

C++11 では、移植可能な char16_t (16 ビット Unicode) および char32_t (32 ビット Unicode) 文字型が導入されています。

auto s3 = u"hello"; // const char16_t*
auto s4 = U"hello"; // const char32_t*

未加工の文字列リテラル (C++11)

未加工文字列リテラルは、(任意の文字型の) null で終わる配列で、二重引用符 (")、円記号 (\)、または改行文字を含む任意のグラフィック文字を含めることができます。 未加工文字列リテラルは、文字クラスを使用する正規表現や、HTML 文字列、XML 文字列でよく使用されます。 例については、記事「 C++11 に関する Bjarne Stroustrup の FAQ」をご覧ください。

// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";
const wchar_t*  raw_wide  = LR"(An unescaped \ character)";
const char*     raw_utf8a = u8R"(An unescaped \ character)"; // Before C++20
const char8_t*  raw_utf8b = u8R"(An unescaped \ character)"; // C++20
const char16_t* raw_utf16 = uR"(An unescaped \ character)";
const char32_t* raw_utf32 = UR"(An unescaped \ character)";

区切り記号は、16 文字以下のユーザー定義のシーケンスです。未加工の文字列リテラルを囲む左かっこの直前および右かっこの直後に配置されます。 たとえば、 R"abc(Hello"\()abc" では、区切り記号シーケンスが abc で、文字列コンテンツが Hello"\(です。 区切り記号を使用することで、二重引用符とかっこの両方を含む未加工の文字列の曖昧さを解消できます。 この文字列リテラルでは、コンパイラ エラーが発生します。

// meant to represent the string: )"
const char* bad_parens = R"()")";  // error C2059

しかし、区切り文字を使用することで、エラーは解決します。

const char* good_parens = R"xyz()")xyz";

次のように、ソースの改行 (エスケープ文字ではない) を含む未加工の文字列リテラルを作成できます。

// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";

std::string リテラル (C++14)

std::string リテラルは、(s サフィックスが付いた) "xyz"s として表されるユーザー定義リテラルの標準ライブラリの実装です (下記参照)。 この種類の文字列リテラルでは、指定されたプレフィックスに応じてstd::stringstd::wstringstd::u32string、または std::u16string の一時オブジェクトが生成されます。 プレフィックスを使用しないと、上記のように、std::string が生成されます。 L"xyz"sstd::wstring を生成します。 u"xyz"sstd::u16string を生成し、U"xyz"sstd::u32string を生成します。

//#include <string>
//using namespace std::string_literals;
string str{ "hello"s };
string str2{ u8"Hello World" };     // Before C++20
u8string u8str2{ u8"Hello World" }; // C++20
wstring str3{ L"hello"s };
u16string str4{ u"hello"s };
u32string str5{ U"hello"s };

s サフィックスは、未加工の文字列リテラルにも使用できます。

u32string str6{ UR"(She said "hello.")"s };

std::string リテラルは、<string> ヘッダー ファイルの名前空間 std::literals::string_literals で定義されます。 std::literals::string_literals、および std::literals はいずれも インライン名前空間として宣言されているため、 std::literals::string_literals は名前空間 stdに直接属しているかのように処理されます。

文字列リテラルのサイズ

ANSI char* 文字列とその他の単一バイト エンコード (UTF-8 以外) の場合、文字列リテラルのサイズ (バイト単位) は、文字数 + 1 (終端の null 文字用) になります。 その他すべての文字列型の場合、サイズと文字数に厳密な関係はありません。 UTF-8 は最大 4 つの char の要素を使用していくつかのコード単位をエンコードします。UTF-16 で符号化された char16_twchar_t では、1 つのコード単位を符号化するために 2 個の要素 (計 4 バイト) を用いることができます。 この例では、ワイド文字列リテラルのサイズがバイト単位で表示されます。

const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);

strlen()wcslen() には終端の null 文字のサイズは含まれないことに注意してください。そのサイズは文字列型の要素のサイズと等しくなります (char* または char8_t* の文字列は 1 バイト、wchar_t* 型または char16_t* 型の文字列は 2 バイト、char32_t* 型の文字列は 4 バイト)。

Visual Studio 2022 バージョン 17.0 より前のバージョンの Visual Studio では、文字列リテラルの最大長は 65,535 バイトです。 この制限は、ナローとワイドの両方の文字列リテラルに適用されます。 Visual Studio 2022 バージョン 17.0 以降では、この制限は解除され、使用可能なリソースによって文字列の長さが制限されます。

文字列リテラルの変更

文字列リテラル (std::string リテラルは含まない) は定数であるため、変更を試みると (たとえば str[2] = 'A') コンパイラ エラーが発生します。

Microsoft 固有の仕様

Microsoft C++ では、文字列リテラルを使用して、非定数の char または wchar_tへのポインターを初期化できます。 この非定数初期化は C99 コードで許可されていますが、C++ 98 では非推奨とされており、C++ 11 では削除されています。 文字列を変更すると、この例のようにアクセス違反が発生します。

wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation

/Zc:strictStrings (字列リテラル型の変換の無効化) コンパイラ オプションを設定すると、文字列リテラルを non_const 文字ポインターに変換したときに、コンパイラからエラーを出力させることができます。 標準に準拠した移植可能なコードの場合に推奨します。 auto キーワードを使用して、文字列リテラル初期化ポインターを宣言することもお勧めします。これにより正しい (const) 型に解決されるためです。 たとえば、このコード例ではコンパイル時に文字列リテラルへの書き込みの試みがキャッチされます。

auto str = L"hello";
str[2] = L'a'; // C3892: you cannot assign to a variable that is const.

場合によっては、実行可能ファイルの領域を節約するために、同じ文字列リテラルをプールできます。 文字列リテラルのプールでは、各参照が文字列リテラルの各インスタンスを指すのではなく、コンパイラにより、特定の文字列リテラルへのすべての参照がメモリ内の同じ場所を指します。 文字列プールを有効にするには、/GF コンパイラ オプションを使用します。

Microsoft 固有のセクションはここで終了です。

隣接する文字列リテラルの連結

隣接するワイド文字列リテラルまたはナロー文字列リテラルは連結されます。 次の宣言は、

char str[] = "12" "34";

次の宣言と同じです。

char atr[] = "1234";

次の宣言も同じです。

char atr[] =  "12\
34";

埋め込みの 16 進数エスケープ コードを使用して文字列リテラルを指定すると、予期しない結果が生じることがあります。 次の例では、ASCII 文字 5 の後に文字列 f、i、v、および e を含む文字列リテラルを作成しようとしています。

"\x05five"

実際の結果は、16 進数値 5F (アンダースコアの ASCII コード) に文字列 i、v、および e が続きます。 正しい結果を得るためには、これらのエスケープ シーケンスのいずれかを使用することができます。

"\005five"     // Use octal literal.
"\x05" "five"  // Use string splicing.

std::stringリテラル (および関連 std::u8stringstd::u16string、および std::u32string) は、basic_string 型に定義されている + 演算子と連結できます。 隣接する文字列リテラルと同じ方法で連結することもできます。 いずれの場合も、次のように文字列のエンコードとサフィックスは一致していなければなりません。

auto x1 = "hello" " " " world"; // OK
auto x2 = U"hello" " " L"world"; // C2308: disagree on prefix
auto x3 = u8"hello" " "s u8"world"z; // C3688, disagree on suffixes

ユニバーサル文字名を持つ文字列リテラル

ネイティブ (未加工でない) 文字列リテラルは、ユニバーサル文字名が文字列型の 1 つ以上の文字としてエンコードできる限り、ユニバーサル文字名を使用して任意の文字を表すことができます。 たとえば、拡張文字を表すユニバーサル文字名は、ANSI コード ページ内のナロー文字列でエンコードすることはできませんが、一部のマルチバイト コード ページ内のナロー文字列、UTF-8 文字列、またはワイド文字列でエンコードすることができます。 C++ 11 では、Unicode のサポートは char16_t*char32_t* 文字列型によって拡張され、C++20 では char8_t 型に拡張されます。

// ASCII smiling face
const char*     s1 = ":-)";

// UTF-16 (on Windows) encoded WINKING FACE (U+1F609)
const wchar_t*  s2 = L"😉 = \U0001F609 is ;-)";

// UTF-8  encoded SMILING FACE WITH HALO (U+1F607)
const char*     s3a = u8"😇 = \U0001F607 is O:-)"; // Before C++20
const char8_t*  s3b = u8"😇 = \U0001F607 is O:-)"; // C++20

// UTF-16 encoded SMILING FACE WITH OPEN MOUTH (U+1F603)
const char16_t* s4 = u"😃 = \U0001F603 is :-D";

// UTF-32 encoded SMILING FACE WITH SUNGLASSES (U+1F60E)
const char32_t* s5 = U"😎 = \U0001F60E is B-)";

関連項目

文字セット
数値、ブール値、およびポインターのリテラル
ユーザー定義リテラル