名前空間
変種
操作

文字列リテラル

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

目次

[編集] 構文

"s-char-seq (任意)" (1)
R"d-char-seq (任意)(r-char-seq (任意))d-char-seq (任意)" (2) (C++11以降)
L"s-char-seq (任意)" (3)
LR"d-char-seq (任意)(r-char-seq (任意))d-char-seq (任意)" (4) (C++11以降)
u8"s-char-seq (任意)" (5) (C++11以降)
u8R"d-char-seq (任意)(r-char-seq (任意))d-char-seq (任意)" (6) (C++11以降)
u"s-char-seq (任意)" (7) (C++11以降)
uR"d-char-seq (任意)(r-char-seq (任意))d-char-seq (任意)" (8) (C++11以降)
U"s-char-seq (任意)" (9) (C++11以降)
UR"d-char-seq (任意)(r-char-seq (任意))d-char-seq (任意)" (10) (C++11以降)

[編集] 解説

s-char-seq - 1つ以上のs-charのシーケンス
s-char - 以下のいずれか
basic-s-char - 翻訳文字集合の文字で、二重引用符"、バックスラッシュ\、または改行文字を除く
d-char-seq - 1つ以上のd-charのシーケンスで、最大16文字長
d-char - 基本文字集合の文字で、括弧、バックスラッシュ、空白を除く
r-char-seq - 1つ以上のr-charのシーケンスで、ただし閉じシーケンス)d-char-seq"を含んではならない
r-char - 翻訳文字集合の文字

 構文  種類 エンコーディング
(1,2)  通常文字列リテラル  const char[N] 通常の文字リテラルエンコーディング
(3,4) ワイド文字列リテラル const wchar_t[N] ワイド文字リテラルエンコーディング
(5,6) UTF-8文字列リテラル

const char[N]

(C++20まで)

const char8_t[N]

(C++20以降)
UTF-8
(7,8) UTF-16文字列リテラル const char16_t[N] UTF-16
(9,10) UTF-32文字列リテラル const char32_t[N] UTF-32

上記の表に示されている型において、Nはエンコードされたコードユニットの数であり、これは以下で決定されます。

通常のおよびUTF-8(C++11以降)文字列リテラルは、まとめて狭い文字列リテラルと呼ばれます。

文字列リテラルを評価すると、静的な記憶域期間を持つ文字列リテラルオブジェクトが生成されます。すべての文字列リテラルが重複しないオブジェクトに格納されるかどうか、および文字列リテラルの連続した評価が同じオブジェクトを生成するか異なるオブジェクトを生成するかは未規定です。

文字列リテラルオブジェクトを変更しようとする効果は未定義です。

bool b = "bar" == 3 + "foobar"; // can be true or false, unspecified
 
const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // undefined behavior

生文字列リテラル

生文字列リテラルは、Rを含むプレフィックスを持つ文字列リテラルです(構文(2,4,6,8,10))。これらはどの文字もエスケープせず、区切り文字d-char-seq ()d-char-seqの間にあるものはすべて文字列の一部となります。終端のd-char-seqは、初期のd-char-seqと同じ文字シーケンスです。

// OK: contains one backslash,
// equivalent to "\\"
R"(\)";
 
// OK: contains four \n pairs,
// equivalent to "\\n\\n\\n\\n"
R"(\n\n\n\n)";
 
// OK: contains one close-parenthesis, two double-quotes and one open-parenthesis,
// equivalent to ")\"\"("
R"-()""()-";
 
// OK: equivalent to "\n)\\\na\"\"\n"
R"a(
)\
a""
)a";
 
// OK: equivalent to "x = \"\"\\y\"\""
R"(x = ""\y"")";
 
// R"<<(-_-)>>"; // Error: begin and end delimiters do not match
// R"-()-"-()-"; // Error: )-" appears in the middle and terminates the literal
(C++11以降)

[編集] 初期化

文字列リテラルオブジェクトは、文字列リテラルのs-charのシーケンスr-charのシーケンス(C++11以降)に対応するコードユニット値のシーケンスと、終端のヌル文字 (U+0000) で、以下の順序で初期化されます。

1) basic-s-charの連続したシーケンス、r-char(C++11以降) 単純なエスケープシーケンス、およびユニバーサル文字名それぞれについて、それが表す文字シーケンスは、文字列リテラルに関連付けられた文字エンコーディングを使用してコードユニットシーケンスにエンコードされます。文字が関連付けられた文字エンコーディングで表現できない場合、プログラムは不適格です。
関連付けられた文字エンコーディングがステートフルである場合、そのような最初のシーケンスは初期エンコーディング状態からエンコードされ、後続の各シーケンスは先行するシーケンスの最終エンコーディング状態からエンコードされます。
2)数値エスケープシーケンスについて、エスケープシーケンス内の数字のシーケンスで表される整数値をvとし、文字列リテラルの配列要素型をT(上記の表参照)とします。
  • vTの表現可能な値の範囲を超えない場合、エスケープシーケンスは値vを持つ単一のコードユニットを生成します。
  • そうでなく、文字列リテラルの構文が(1)または(3)であり、(C++11以降) vTの基になる型の対応する符号なし型の表現可能な値の範囲を超えない場合、エスケープシーケンスは、v mod 2S
    に合同であるような、型Tのユニークな値を持つ単一のコードユニットを生成します。ここでSTの幅です。
  • それ以外の場合、プログラムは不適格となります。
関連付けられた文字エンコーディングがステートフルである場合、これらすべてのシーケンスはエンコーディング状態に影響を与えません。
3)条件付きエスケープシーケンスは、実装定義のコードユニットシーケンスを生成します。
関連付けられた文字エンコーディングがステートフルである場合、これらのシーケンスがエンコーディング状態に与える影響は実装定義です。

[編集] 連結

隣接する文字列リテラルは、翻訳フェーズ6 (プリプロセッシング後) で連結されます。

  • 2つの文字列リテラルが同じ種類である場合、連結された文字列リテラルもその種類になります。
  • 通常の文字列リテラルがワイド文字列リテラルに隣接している場合、動作は未定義です。
(C++11まで)
  • 通常の文字列リテラルが非通常の文字列リテラルに隣接している場合、連結された文字列リテラルは後者の種類になります。
  • UTF-8文字列リテラルがワイド文字列リテラルに隣接している場合、プログラムは不適格です。
  • その他の組み合わせは、実装定義のセマンティクスで条件付きでサポートされます。[1]
(C++23まで)
  • その他の組み合わせは不適格です。
(C++23から)
(C++11以降)
"Hello, " "world!" // at phase 6, the 2 string literals form "Hello, world!"
 
L"Δx = %" PRId16   // at phase 4, PRId16 expands to "d"
                   // at phase 6, L"Δx = %" and "d" form L"Δx = %d"
  1. このような連結をサポートする既知の実装はありません。

[編集] 未評価の文字列

以下のコンテキストでは文字列リテラルを期待しますが、評価はしません。

(C++11以降)
(C++14以降)
(C++20以降)
(C++26以降)


これらのコンテキストで非通常の文字列リテラルが許可されるかは未規定です。ただし、リテラル演算子名は通常の文字列リテラルを使用しなければなりません(C++11以降)

(C++26まで)

これらのコンテキストでは、通常の文字列リテラルのみが許可されます。

未評価の文字列内の各ユニバーサル文字名と各単純なエスケープシーケンスは、それが表す翻訳文字集合のメンバに置き換えられます。数値エスケープシーケンスまたは条件付きエスケープシーケンスを含む未評価の文字列は不適格です。

(C++26以降)

[編集] 備考

文字列リテラルは、文字配列を初期化するために使用できます。char str[] = "foo";のように配列が初期化された場合、strには文字列"foo"のコピーが含まれます。

文字列リテラルは、Cとの互換性のために、非constchar*またはwchar_t*に変換および代入可能です。Cでは、文字列リテラルは型char[N]およびwchar_t[N]です。このような暗黙の変換は非推奨です。

(C++11まで)

文字列リテラルは、非constCharT*に変換または代入できません。そのような変換が必要な場合は、明示的なキャスト(例:const_cast)を使用する必要があります。

(C++11以降)

文字列リテラルは必ずしもヌル終端の文字シーケンスであるとは限りません。文字列リテラルが埋め込みヌル文字を含む場合、複数の文字列を含む配列を表します。

const char* p = "abc\0def"; // std::strlen(p) == 3, but the array has size 8

文字列リテラル内の16進エスケープシーケンスの後に有効な16進数字が続く場合、無効なエスケープシーケンスとしてコンパイルエラーになります。文字列連結を回避策として使用できます。

//const char* p = "\xfff"; // error: hexadecimal escape sequence out of range
const char* p = "\xff""f"; // OK: the literal is const char[3] holding {'\xff','f','\0'}
機能テストマクロ 規格 機能
__cpp_char8_t 202207L (C++23)
(DR20)
char8_t互換性と移植性の修正(UTF-8文字列リテラルからの(unsigned) char配列の初期化を許可)
__cpp_raw_strings 200710L (C++11) 生文字列リテラル
__cpp_unicode_literals 200710L (C++11) Unicode文字列リテラル

[編集]

#include <iostream>
 
// array1 and array2 contains the same values:
char array1[] = "Foo" "bar";
char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'};
 
const char* s1 = R"foo(
Hello
  World
)foo";
// same as
const char* s2 = "\nHello\n  World\n";
// same as
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";
 
const wchar_t* s4 = L"ABC" L"DEF"; // OK, same as
const wchar_t* s5 = L"ABCDEF";
const char32_t* s6 = U"GHI" "JKL"; // OK, same as
const char32_t* s7 = U"GHIJKL";
const char16_t* s9 = "MN" u"OP" "QR"; // OK, same as
const char16_t* sA = u"MNOPQR";
 
// const auto* sB = u"Mixed" U"Types";
        // before C++23 may or may not be supported by
        // the implementation; ill-formed since C++23
 
const wchar_t* sC = LR"--(STUV)--"; // OK, raw string literal
 
int main()
{
    std::cout << array1 << ' ' << array2 << '\n'
              << s1 << s2 << s3 << std::endl;
    std::wcout << s4 << ' ' << s5 << ' ' << sC
               << std::endl;
}

出力

Foobar Foobar
 
Hello
  World
 
Hello
  World
 
Hello
  World
 
ABCDEF ABCDEF STUV

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 411
(P2029R4)
C++98 文字列リテラルのエスケープシーケンスは
複数のコードユニットにマップすることを許可されていなかった
許可
CWG 1656
(P2029R4)
C++98 文字列リテラルの数値エスケープ
シーケンスが表す文字が不明確だった
明確化された
CWG 1759 C++11 UTF-8文字列リテラルはchar
表現できないコードユニットを持つ可能性がある
charはすべてのUTF-8コードユニットを表現できる
CWG 1823 C++98 文字列リテラルが異なるかどうかは
実装定義だった
異なるかどうかは未規定であり、同じ
文字列リテラルでも異なるオブジェクトを生成する可能性がある
CWG 2333
(P2029R4)
C++11 UTF-8/16/32文字列リテラルで数値エスケープシーケンスが
許可されているかどうかが不明確だった
明確化された
CWG 2870 C++11 2つの通常の文字列リテラルの
連結結果が不明確だった
明確化された
P1854R4 C++98 エンコードできない文字を含む通常の文字列リテラルとワイド文字列リテラルは
条件付きでサポートされていた
そのようなリテラルを含むプログラムは不適格
P2029R4 C++98 1. 文字列リテラルがエンコードできない文字を
    含むことができるかどうか不明確だった
2. 文字列リテラルが数値エスケープシーケンスを
    含むことができるかどうか不明確だった。それらのコードユニットが
    リテラルの配列要素型で表現できないような場合。
    
1. 通常の文字列リテラルとワイド文字列リテラルについては
    条件付きサポートとした[1]
2. コードユニットが
    基になる型に対応する
    符号なし整数型でも表現できない場合、
    不適格
  1. P1854R4が後にDRとして受理され、この解決策を上書きしました。

[編集] 参照

  • C++23標準 (ISO/IEC 14882:2024)
  • 5.13.5 文字列リテラル [lex.string]
  • C++20 standard (ISO/IEC 14882:2020)
  • 5.13.5 文字列リテラル [lex.string]
  • C++17 standard (ISO/IEC 14882:2017)
  • 5.13.5 文字列リテラル [lex.string]
  • C++14 standard (ISO/IEC 14882:2014)
  • 2.14.5 文字列リテラル [lex.string]
  • C++11 standard (ISO/IEC 14882:2011)
  • 2.14.5 文字列リテラル [lex.string]
  • C++03 標準 (ISO/IEC 14882:2003)
  • 2.13.4 文字列リテラル [lex.string]
  • C++98 標準 (ISO/IEC 14882:1998)
  • 2.13.4 文字列リテラル [lex.string]

[編集] 関連項目

ユーザー定義リテラル(C++11) ユーザー定義サフィックス付きリテラル[編集]
Cドキュメント文字列リテラル
English 日本語 中文(简体) 中文(繁體)