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 字組和補充字元 (英文)。