共用方式為


C++ 字串常值

字串常值代表構成 null 結束字串的一連串字元。 這些字元必須使用雙引號括起來。 有下列字串常值類型:

  • 窄字串常值,以 "xxx" 表示。

  • 寬字串常值,以 L"xxx" 表示。

  • 原始字串常值,表示為 R"ddd(xxx) ddd",其中 ddd 是分隔符號。 原始字串常值 (String Literal) 可能是窄的 (以 R 表示) 或寬的 (以 LR 表示)。

窄字串常值是包含任何圖形字元 (雙引號 (")、反斜線 (\) 或新行字元以外) 的 null 結束 char 常數陣列。 窄字串常值可能包含 C++ 字元常值中所列的逸出序列。

const char *narrow = "abcd";

// represents the string: yes\no
const char *escaped = "yes\\no";

寬字串常值是包含任何圖形字元 (雙引號 (")、反斜線 (\) 或新行字元以外) 的 null 結束 wchar_t 常數陣列。 寬字串常值可能包含 C++ 字元常值中所列的逸出序列。

const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";

原始字串常值是 null 結束陣列 (為常數 char 或常數 wchar_t),其中包含任何圖形字元,包括雙引號 (")、反斜線 (\) 或新行字元。 原始字串常值通常用於使用字元類別的規則運算式,以及 HTML 字串和 XML 字串。 如需範例,請參閱下列文章:Bjarne Stroustrup 的 C++11 常見問題集 (英文)。

// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";

// represents the string: An unescaped " character
const wchar_t* raw_wide = LR"(An unescaped " character)";

分隔符號是使用者定義的順序,最多包含 16 個字元,在原始字串常值的左括號前面、右括號後面。 您可以使用分隔符號,釐清包含雙引號和括號的字串。 這會造成編譯器錯誤:

// meant to represent the string: )”
const char* bad_parens = R"()")";

但是分隔符號解決這個錯誤:

const char* good_parens = R"xyz()")xyz";

您可以在來源中建構有新行字元 (不是逸出字元) 的原始字串常值:

// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";

字串常值的大小

窄字串常值的大小 (以位元組為單位) 是字元數加 1 (結束的 null 字元),而寬字串常值的大小 (以位元組為單位) 是字元數乘 2 加上 2 (結束的 null 字元)。 這會顯示寬字串常值的大小:

const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);

請注意,strlen() 和 wcslen() 不包含結束的 null 字元的大小。

字串常值的長度上限為 65535 個位元組。 這個限制適用於窄字串常值和寬字串常值。

修改字串常值

由於字串常值是常數,因此嘗試加以修改 (例如 str[2] = 'A') 會造成編譯器錯誤。

Microsoft 特定的

在 Visual C++ 中,您可以使用字串常值,初始化非常數 char 或 wchar_t 的指標。 C 程式碼允許這項功能,不過在 C++98 中已被取代,在 C++11 中已移除。 嘗試修改字串造成存取違規,如此範例所示:

wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation

當您設定 /Zc:strictStrings (停用字串常值型別轉換) 編譯器選項時,您可以讓編譯器在字串常值轉換為 non_const 字元時發出錯誤。 比較好的做法是使用 auto 關鍵字,宣告字串常值初始化的指標,因為這會解析成正確 (常數) 類型。 例如,這個範例會攔截在編譯時期嘗試寫入字串常值的動作:

auto str = L"hello";
str[2] = L'a'; // Compiler error: you cannot assign to a variable that is const

在某些情況下,可以結合相同字串常值來節省可執行檔中的空間。 在字串常值共用中,編譯器會讓特定字串常值的所有參考指向記憶體內部相同位置,而不是讓每個參考都指向字串常值的個別執行個體。 若要啟用字串共用,請使用 /GF 編譯器選項。

結束 Microsoft 專有

串連相鄰的字串常值

會串連相鄰的字串常值。 這個宣告:

char str[] = "12" "34";

等同於此宣告:

char atr[] = "1234";

以及這個宣告:

char atr[] =  "12\
34";

使用內嵌十六進位逸出程式碼指定字串常數可能造成未預期的結果。 下列範例是要建立包含 ASCII 5 字元的字串常值,後面接著字元 f、i、v 和 e:

"\x05five"

實際結果是十六進位 5F (即底線字元的 ASCII 碼),後面接 i、v、e 字元。 若要取得正確結果,您可以使用其中一個:

"\005five"     // Use octal constant.
"\x05" "five"  // Use string splicing.

含 Unicode 字元的字串常值

Surrogate 字組和補充字元 (如同 UTF-16) 會以 \U 前置詞表示。 這些是寬字串而非單一字元,而且用雙引號表示而非單引號。 不支援前置詞 U、u 和 u8。

const wchar_t* str1 = L"\U0002008A";
const wchar_t* str2 = L"\UD869DED6";
const wchar_t* str3 = L"\Udc00c800";

如需 Unicode 的詳細資訊,請參閱 Unicode (英文)。 如需 Surrogate 字組的詳細資訊,請參閱 Surrogate 字組和補充字元 (英文)。

請參閱

參考

C++ 常值