文字列リテラル
目次 |
[編集] 構文
" (unescaped_character|escaped_character)* "
|
(1) | ||||||||
L" (unescaped_character|escaped_character)* "
|
(2) | ||||||||
u8" (unescaped_character|escaped_character)* "
|
(3) | (C++11以上) | |||||||
u" (unescaped_character|escaped_character)* "
|
(4) | (C++11以上) | |||||||
U" (unescaped_character|escaped_character)* "
|
(5) | (C++11以上) | |||||||
prefix(オプション) R" delimiter( raw_characters ) delimiter"
|
(6) | (C++11以上) | |||||||
[編集] 説明
unescaped_character | - | ダブルクォート "、バックスラッシュ \、改行文字を除いた、任意の有効な文字 |
escaped_character | - | エスケープシーケンスを参照してください |
prefix | - | L 、 u8 、 u 、 U のいずれか
|
delimiter | - | 括弧、バックスラッシュ、スペースを除いた任意のソース文字から構成される文字シーケンス (空でも構いません) (最大16文字) |
raw_characters | - | 閉じシーケンス ) delimiter" を含まない任意の文字シーケンス
|
N
は実行ナローエンコーディングのコードユニットで数えた文字列のサイズです (ヌル終端を含みます)。N
は実行ワイドエンコーディングのコードユニットで数えた文字列のサイズです (ヌル終端を含みます)。N
は UTF-8 コードユニットで数えた文字列のサイズです (ヌル終端を含みます)。N
は UTF-16 コードユニットで数えた文字列のサイズです (ヌル終端を含みます)。N
は UTF-32 コードユニットで数えた文字列のサイズです (ヌル終端を含みます)。[編集] ノート
ヌル文字 ('\0'、 L'\0'、 char16_t() など) が文字列リテラルに必ず追加されます。 そのため、文字列リテラル "Hello" は文字 'H'、 'e'、 'l'、 'l'、 'o' および '\0' を保持する const char[6] です。
ナローマルチバイト文字列リテラル (1) およびワイド文字列リテラル (2) のエンコーディングは処理系定義です。 例えば、 gcc はコマンドラインオプション -fexec-charset および -fwide-exec-charset でそれらを選択します。
並んで置かれた文字列リテラルは翻訳フェーズ6 (プリプロセッサの後) で連結されます。 つまり、 "Hello," " world!" は単一の文字列 "Hello, world!" を生成します。 2つの文字列が同じエンコーディング接頭辞を持つ (またはどちらも接頭辞を持たない) 場合、結果の文字列はそれと同じ接頭辞を持ちます (または接頭辞を持ちません)。
文字列の一方がエンコーディング接頭辞を持ち、他方が持たない場合、後者は前者と同じエンコーディング接頭辞を持つとみなされます。 L"Δx = %" PRId16 // フェーズ4で、 PRId16 は "d" に展開されます。 // フェーズ6で、 L"Δx = %" と "d" は L"Δx = %d" を形成します。 UTF-8 文字列リテラルとワイド文字列リテラルが並んでいる場合、プログラムは ill-formed です。 |
(C++11以上) |
エンコーディング接頭辞のそれ以外のあらゆる組み合わせは、処理系によってサポートされるかもしれませんし、されないかもしれません。 そのような組み合わせの結果は処理系定義です。
文字列リテラルは静的記憶域期間を持ち、そのためプログラムの生存の間、メモリに存在します。
文字列リテラルは文字配列を初期化するために使用することができます。 配列が char str[] = "foo"; のように初期化された場合、 str は文字列 "foo" のコピーを格納します。
コンパイラは等しいまたはオーバーラップする文字列リテラルのための記憶域を結合することが許されていますが必須ではありません。 これは同一の文字列リテラルをポインタで比較したときに等しいかもしれないし等しくないかもしれないことを意味します。
bool b = "bar" == 3+"foobar" // true にも false になり得ます (処理系定義)
文字列リテラルを変更する試みは未定義動作です。 これらは読み込み専用の記憶域 (.rodata
など) に格納されるかもしれませんし、他の文字列リテラルと結合されているかもしれません。
const char* pc = "Hello"; char* p = const_cast<char*>(pc); p[0] = 'M'; // 未定義動作
C では、文字列リテラルは char[] 型であり、 (const でない) char* に直接代入できます。 C++03 は同様にこれを認めていました (が、非推奨であり、 C++ ではリテラルは const でした)。 C++11 はもはやキャストなしにはそのような代入を許可しません。
文字列は C の文字列であるとは限りません。 文字列リテラルにヌル文字が埋め込まれている場合、それは複数の文字列を含む配列を表します。
const char* p = "abc\0def"; // std::strlen(p) == 3 ですが、配列のサイズは 8 です。
文字列リテラル内で有効な16進数字が16進エスケープの後に続く場合、それは無効なエスケープシーケンスとしてコンパイルに失敗します。 ワークアラウンドとして文字列の連結が使用できます。
//const char* p = "\xfff"; // エラー。 16進エスケープが範囲外です。 const char* p = "\xff""f"; // OK。 リテラルは {'\xff','f','\0'} を保持する const char[3] です。
[編集] 例
#include <iostream> char array1[] = "Foo" "bar"; // 以下と同じです。 char array2[] = { 'F', 'o', 'o', 'b', 'a', 'r', '\0' }; const char* s1 = R"foo( Hello World )foo"; // 以下と同じです。 const char* s2 = "\nHello\nWorld\n"; int main() { std::cout << array1 << '\n'; std::cout << array2 << '\n'; std::cout << s1; std::cout << s2; }
出力:
Foobar Foobar Hello World Hello World
[編集] 関連項目
ユーザ定義リテラル(C++11) | ユーザ定義の接尾辞を持つリテラル |
文字列リテラル の C言語リファレンス
|