命名空间
变体
操作

字符串字面量

来自 cppreference.cn
< 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 文档 关于 字符串字面量