名稱空間
變體
操作

字串字面量

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

目錄

[編輯] 語法

"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 - 一個或多個 s-char 的序列
s-char - 以下之一
basic-s-char - 來自翻譯字元集的字元,除了雙引號 "、反斜槓 \ 或換行符
d-char-seq - 一個或多個 d-char 的序列,最長 16 個字元
d-char - 來自基本字元集的字元,除了括號、反斜槓和空格
r-char-seq - 一個或多個 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 為字串字面量的陣列元素型別(參見上方表格)
  • 如果 v 不超過 T 的可表示值範圍,則轉義序列貢獻一個碼元,其值為 v
  • 否則,如果字串字面量是語法 (1)(3),且(C++11 起) v 不超過 T 的底層型別所對應的無符號型別的可表示值範圍,則轉義序列貢獻一個碼元,其型別為 T,唯一值為 v mod 2S
    ,其中 ST 的位寬。
  • 否則,程式格式錯誤。
如果相關字元編碼是有狀態的,則所有此類序列對編碼狀態沒有影響。
3) 每個條件轉義序列貢獻一個實現定義的碼元序列。
如果相關字元編碼是有狀態的,則這些序列對編碼狀態的影響是實現定義的。

[編輯] 連線

相鄰的字串字面量在翻譯階段 6(預處理後)進行連線

  • 如果兩個字串字面量屬於相同種類,則連線後的字串字面量也屬於該種類。
  • 如果一個普通字串字面量與一個寬字串字面量相鄰,則行為未定義。
(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 相容,字串字面量可轉換為並賦值給非 const char*wchar_t*,在 C 中字串字面量的型別是 char[N]wchar_t[N]。此類隱式轉換已被棄用。

(C++11 前)

字串字面量不可轉換為或賦值給非 const CharT*。如果需要此類轉換,必須使用顯式型別轉換(例如 const_cast)。

(C++11 起)

字串字面量不一定是空終止字元序列:如果字串字面量包含嵌入的空字元,它表示一個包含多個字串的陣列。

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

如果在字串字面量中的十六進位制轉義序列後跟著一個有效的十六進位制數字,它將因無效轉義序列而編譯失敗。可以使用字串連線作為變通方法

//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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
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 兩個普通字串字面量的連線結果
不明確
已明確
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 標準 (ISO/IEC 14882:2020)
  • 5.13.5 字串字面量 [lex.string]
  • C++17 標準 (ISO/IEC 14882:2017)
  • 5.13.5 字串字面量 [lex.string]
  • C++14 標準 (ISO/IEC 14882:2014)
  • 2.14.5 字串字面量 [lex.string]
  • C++11 標準 (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 文件 關於 字串字面量