Share via


字串 (C++/CX)

Windows 執行階段中的文字是由 Platform::String 類別 以 C++/CX 表示。 Platform::String Class當您將字串來回傳遞至Windows 執行階段類別中的方法,或當您跨應用程式二進位介面 (ABI) 界限與其他Windows 執行階段元件互動時,請使用 。 Platform::String Class 提供適用於幾個常見字串作業的方法,但它並不是針對完整功能的字串類別而設計的。 您可以在 C++ 模組中使用 Standard C++ 字串型别 (如 wstring ) 進行任何重要的文字處理,然後將最終的結果轉換成 Platform::String^ ,再將其傳入或傳出公用介面。 wstringwchar_t*Platform::String之間可進行簡單而有效的轉換。

快速傳遞

在某些情況下,編譯器可確認無需先行複製基礎字串資料,即可安全地建構 Platform::String 或將 String 傳遞至函式。 這類作業稱為「 快速傳遞 」(Fast Pass),可以明確地執行。

字串建構

String 物件的值是 char16 (16 位元 Unicode) 字元不可變的 (唯讀) 序列。 由於 String 物件是不可變的,因此在指派新的字串常值指派給 String 變數後,即會將原始的 String 物件取代為新的 String 物件。 串連作業包含原始 String 物件的解構與新物件的建立。

常值

常值字元 」(Literal Character) 是包含在單引號中的字元,而「 常值字串 」(Literal String) 則是包含在雙引號中的字元序列。 如果您使用常值初始化 String^ 變數,編譯器會假設常值包含 char16 字元。 也就是說,您無需在常值之前加上 'L' 字串修飾詞,或是將常值納入 _T()TEXT() 巨集中。 如需 C++ 之 Unicode 支援的詳細資訊,請參閱 Unicode Programming Summary

下列範例說明各種建構 String 物件的方式。

// Initializing a String^ by using string literals
String^ str1 = "Test"; // ok for ANSI text only. uses current code page
String^ str2("Test");
String^ str3 = L"Test";
String^ str4(L"Test");


//Initialize a String^ by using another String^
String^ str6(str1);
auto str7 = str2;

// Initialize a String from wchar_t* and wstring
wchar_t msg[] = L"Test";
String^ str8 = ref new String(msg);
std::wstring wstr1(L"Test");
String^ str9 = ref new String(wstr1.c_str());
String^ str10 = ref new String(wstr1.c_str(), wstr1.length());

字串處理作業

String 類別會提供串連字串、比較字串與其他基本字串作業所需的方法與運算子。 若要執行更廣泛的字串管理,請使用 String::Data() 成員函式來擷取 String^ 物件的值,做為 const wchar_t*。 接著請使用該值初始化 std::wstring,以提供多樣化的字串處理函式。


 // Concatenation 
 auto str1 = "Hello" + " World";
 auto str2 = str1 + " from C++/CX!";    
 auto str3 = String::Concat(str2, " and the String class");
 
 // Comparison
 if (str1 == str2) { /* ... */ }
 if (str1->Equals(str2)) { /* ... */ }
 if (str1 != str2) { /* ... */ }
 if (str1 < str2 || str1 > str2) { /* ... */};
 int result = String::CompareOrdinal(str1, str2);
 
 if(str1 == nullptr) { /* ...*/};
 if(str1->IsEmpty()) { /* ...*/};

// Accessing individual characters in a String^
 auto it = str1->Begin();
 char16 ch = it[0];

字串轉換

Platform::String 只能包含 char16 字元或 NULL 字元。 如果您的應用程式必須使用 8 位字元,請使用 String::D ata 將文字擷取為 const wchar_t* 。 接著,您可以使用適當的 Windows 函式或標準程式庫函式來處理資料,並將其重新轉換成 wchar_t*wstring,供您用以建構新的 Platform::String表示。

下列程式碼片段說明如何在 String^ 變數與 wstring 變數之間轉換。 如需此範例中使用之字串操作的詳細資訊,請參閱 basic_string::replace

// Create a String^ variable statically or dynamically from a literal string. 
String^ str1 = "AAAAAAAA";

// Use the value of str1 to create the ws1 wstring variable.
std::wstring ws1( str1->Data() ); 
// The value of ws1 is L"AAAAAAAA".

// Manipulate the wstring value.
std::wstring replacement( L"BBB" );
ws1 = ws1.replace ( 1, 3, replacement );
// The value of ws1 is L"ABBBAAAA".

// Assign the modified wstring back to str1. 
str1 = ref new String( ws1.c_str() ); 

字串長度與內嵌的 NULL 值

String::Length 傳回字串中的字元數,而不是位元組數目。 結尾的 NULL 字元不會計入字元數,除非您在使用堆疊語意建構字串時明確加以指定。

Platform::String 可包含內嵌 NULL 值,但僅限於 NULL 是串連作業的結果時。 字串常值不支援內嵌 NULL,因此您無法以該格式使用內嵌 NULL 初始化 Platform::String。 字串顯示時, Platform::String 中的內嵌 NULL 值會被忽略,例如在字串指派給 TextBlock::Text 屬性時。 Data 屬性傳回字串值時,會移除內嵌的 NULL。

StringReference

在某些情況下,您的程式碼 (a) 會收到 std::wstring,或wchar_t string 或 L「」 字串常值,並直接將它傳遞給另一個接受 String^ 做為輸入參數的方法。 只要原始字串緩衝區保持有效,而且在函式傳回前不會變動,您可以將 wchar_t* 字串或字串常值轉換成 Platform::StringReference,並傳入後者而不傳入 Platform::String^。 因為 StringReference 具有轉換為 Platform::String^的使用者定義轉換,所以允許這個作業。 使用 StringReference ,可以避免建立字串資料的額外複本。 在傳遞大量字串的迴圈中,或在傳遞非常大型的字串時,透過使用 StringReference,效能可能會顯著改善。 但是因為 StringReference 基本上借用原始字串緩衝區,您必須非常小心避免記憶體損毀。 除非原始字串在這個方法傳回時保證在範圍內,否則不應該將 StringReference 傳遞至非同步方法。 從 StringReference 初始化的 String^ 會在第二個指派作業發生時,強制字串資料的配置和複製。 在這種情況下,將會遺失 StringReference的效能優勢。

請注意, StringReference 是 Standard C++ 類別型別,不是 ref 類別,無法用於您定義的 ref 類別公用介面。

下列範例示範如何使用 StringReference:

void GetDecodedStrings(std::vector<std::wstring> strings)
{
    using namespace Windows::Security::Cryptography;
    using namespace Windows::Storage::Streams;

    for (auto&& s : strings)
    {
        // Method signature is IBuffer^ CryptographicBuffer::DecodeFromBase64String (Platform::String^)
        // Call using StringReference:
        IBuffer^ buffer = CryptographicBuffer::DecodeFromBase64String(StringReference(s.c_str()));

        //...do something with buffer
    }
}