命名空间
变体
操作

字符串字面量

来自 cppreference.com
< cpp‎ | language
 
 
C++ 语言
表达式
替代表示
字面量
布尔值 - 整数 - 浮点数
字符 - 字符串 - 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 - 一个或多个 s-char s 的序列
s-char - 以下之一
basic-s-char - 来自 翻译字符集 的一个字符,但双引号 "、反斜杠 \ 或换行符除外
d-char-seq - 一个或多个 d-char s 的序列,长度最多 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 s r-char s(从 C++11 开始) 序列相对应的代码单元值序列初始化,加上一个结束空字符 (U+0000),顺序如下

1) 对于每个连续的 basic-s-char s r-char s(从 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'}
功能测试 Std 功能
__cpp_char8_t 202207L (C++20)
(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 两个
普通字符串字面量的连接结果不清楚
已澄清
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 文档 适用于 字符串字面量