C++ 文字列リテラル
文字列リテラルは文字のシーケンスを表し、その全体が、null で終わる文字列を形成します。 文字列は二重引用符で囲む必要があります。 文字列リテラルの種類は次のとおりです。
ナロー文字列リテラル。"xxx" と表されます。
ワイド文字列リテラル。L"xxx" と表されます。
未加工の文字列リテラル。R"ddd(xxx) ddd" と表されます。ここで、ddd は区切り文字です。 未加工の文字列リテラルは、ナロー (R と表される) またはワイド (LR と表される) です。
ナロー文字列リテラルは、null で終わる定数 char の配列です。二重引用符 (")、円記号 (\)、または改行文字を除く任意のグラフィック文字を含めることができます。 ナロー文字列リテラルには、「C++ 文字リテラル」に示すエスケープ シーケンスが含まれる場合があります。
const char *narrow = "abcd";
// represents the string: yes\no
const char *escaped = "yes\\no";
ワイド文字列リテラルは、null で終わる定数 wchar_t の配列です。二重引用符 (")、円記号 (\)、または改行文字を除く任意のグラフィック文字を含めることができます。 ワイド文字列リテラルには、「C++ 文字リテラル」に示すエスケープ シーケンスが含まれる場合があります。
const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";
未加工文字列リテラルは、null で終わる定数 char または定数 wchar_t の配列です。二重引用符 (")、円記号 (\)、または改行文字を含む任意のグラフィック文字を含めることができます。 未加工文字列リテラルは、文字クラスを使用する正規表現や、HTML 文字列、XML 文字列でよく使用されます。 例については、 「C++11 に関する Bjarne Stroustrup の FAQ」を参照してください。
// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";
// represents the string: An unescaped " character
const wchar_t* raw_wide = LR"(An unescaped " character)";
区切り記号は、16 文字以下のユーザー定義のシーケンスです。未加工の文字列リテラルを囲む左かっこの直前および右かっこの直後に配置されます。 区切り記号を使用することで、二重引用符とかっこの両方を含む文字列のあいまいさを解消できます。 次のコードではコンパイラ エラーが発生します。
// meant to represent the string: )”
const char* bad_parens = R"()")";
しかし、区切り文字を使用することで、エラーは解決します。
const char* good_parens = R"xyz()")xyz";
次のソースでは、改行 (エスケープ文字ではない) を含む未加工リテラルを作成できます。
// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";
文字列リテラルのサイズ
ナロー文字列リテラルのバイト単位のサイズは、文字数 + 1 (終端の null 文字) です。ワイド文字列リテラルのバイト単位のサイズは、文字数 x 2 + 2 (終端の null 文字) です。 次のコードでは、ワイド文字列リテラルのサイズが表示されます。
const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);
strlen() と wcslen() には、終端の null 文字のサイズが含まれていないことに注意してください。
文字列リテラルの最大長は 65535 バイトです。 この制限は、ナローとワイドの両方の文字列リテラルに適用されます。
文字列リテラルの変更
文字列リテラルは定数であるため、変更すると (str[2] = 'A' などにすると)、コンパイラ エラーが発生します。
Microsoft 固有の仕様 →
Visual C++ では、文字列リテラルを使用して、非定数の char または wchar_t へのポインターを初期化できます。 この操作は C のコードで使用できますが、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'; // Compiler error: you cannot assign to a variable that is const
場合によっては、実行可能ファイルの領域を節約するために、同じ文字列リテラルをプールできます。 文字列リテラルのプールでは、各参照が文字列リテラルの各インスタンスを指すのではなく、コンパイラにより、特定の文字列リテラルへのすべての参照がメモリ内の同じ場所を指します。 文字列プールを有効にするには、/GF コンパイラ オプションを使用します。
END 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 constant.
"\x05" "five" // Use string splicing.
Unicode 文字を使用した文字列リテラル
サロゲート ペアと補助文字 (UTF-16 などの場合) はプレフィックス \U を付けて表されます。 これらは単一文字ではなくワイド文字列であり、単一引用符ではなく二重引用符で表されます。 U、u、および u8 プレフィックスはサポートされていません。
const wchar_t* str1 = L"\U0002008A";
const wchar_t* str2 = L"\UD869DED6";
const wchar_t* str3 = L"\Udc00c800";
Unicode の詳細については、「Unicode」を参照してください。 サロゲート ペアの詳細については、「Surrogate Pairs and Supplementary Characters (サロゲート ペアと補助文字)」を参照してください。