Zeichenfolgen (C++/CX)

Text in der Windows-Runtime wird in C++/CX durch die Platform::String-Klasse dargestellt. Verwenden Sie, Platform::String Class wenn Sie Zeichenfolgen an Methoden in Windows-Runtime Klassen übergeben, oder wenn Sie mit anderen Windows-Runtime Komponenten über die ABI-Grenze (Application Binary Interface) interagieren. Die Platform::String Class stellt Methoden für einige allgemeine Zeichenfolgenoperationen bereit, aber sie ist nicht als umfassende Zeichenfolgenklasse gedacht. Verwenden Sie in Ihrem C++-Modul Standard-C++-Zeichenfolgentypen wie wstring für sämtliche wesentliche Textverarbeitung und konvertieren Sie dann das Endergebnis zu Platform::String , bevor Sie es zu oder von einer öffentlichen Schnittstelle übergeben. Das Konvertieren zwischen wstring oder wchar_t* und Platform::Stringist einfach und effizient.

Fastpass

In einigen Fällen kann der Compiler überprüfen, ob er eine Platform::String sicher erstellen oder eine String an eine Funktion übergeben werden kann, ohne die zugrunde liegenden Zeichenfolgendaten zu kopieren. Solche Vorgänge werden als Fast Pass bezeichnet und sie treten transparent auf.

Zeichenfolgenkonstruktion

Der Wert eines String -Objekts ist eine unveränderliche (schreibgeschützte) Sequenz von char16 (16-Bit-Unicode)-Zeichen. Da ein String -Objekt unveränderlich ist, ersetzt die Zuweisung eines neuen Zeichenfolgenliterals zu einer String -Variable tatsächlich das ursprüngliche String -Objekt durch ein neues String -Objekt. Verkettungsvorgänge umfassen die Zerstörung des ursprünglichen String -Objekts und die Erstellung eines neuen Objekts.

Literale

Ein Literalzeichen ist ein Zeichen, das in einfache Anführungszeichen eingeschlossen ist, und eine Literalzeichenfolge ist eine Sequenz von Zeichen, die in Anführungszeichen eingeschlossen ist. Wenn Sie ein Literal verwenden, um eine String^-Variable zu initialisieren, nimmt der Compiler an, dass das Literal aus char16 -Zeichen besteht. Das heißt, dem Literal muss kein „L“-Zeichenfolgenmodifizierer vorausgehen und es muss nicht in einem _T() oder TEXT() -Makro eingeschlossen werden. Weitere Informationen zur C++-Unterstützung für Unicode finden Sie unter Unicode Programming Summary.

Im folgenden Beispiel werden verschiedene Möglichkeiten veranschaulicht, um String -Objekte zu erstellen.

// 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());

Zeichenfolgenbehandlungsvorgänge

Die String -Klasse stellt Methoden und Operatoren für das Verketten bereit und vergleicht Zeichenfolgen und andere grundlegender Zeichenfolgenoperationen. Um umfangreichere Zeichenfolgenbearbeitungen auszuführen, verwenden Sie die String::Data() -Memberfunktion um den Wert des String^ -Objekts als const wchar_t*abzurufen. Verwenden Sie dann diesen Wert, um std::wstringzu initialisieren, der umfangreiche Funktionen für die Zeichenfolgenbehandlung bereitstellt.


 // 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];

Zeichenfolgenkonvertierung

Eine Platform::String kann nur char16 -Zeichen oder das NULL -Zeichen enthalten. Wenn Ihre Anwendung mit 8-Bit-Zeichen arbeiten muss, verwenden Sie die Zeichenfolge::D ata , um den Text als eine const wchar_t*zu extrahieren. Sie können dann die entsprechenden Windows-Funktionen oder Standardbibliotheksfunktionen verwenden, um die Daten zu bearbeiten und sie zurück zu einer wchar_t* oder wstringzu konvertieren. Diese können Sie dann verwenden, um neue Platform::Stringdargestellt.

Das folgende Codefragment zeigt, wie eine String^ -Variable in eine und aus einer wstring -Variable konvertiert wird. Weitere Informationen zu der in diesem Beispiel verwendeten Zeichenfolgenbearbeitung finden Sie unter 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() ); 

Zeichenfolgenlänge und eingebettete NULL-Werte

Die Zeichenfolge::Length gibt die Anzahl der Zeichen in der Zeichenfolge zurück, nicht die Anzahl der Bytes. Das abschließende NULL-Zeichen wird nicht gezählt, es sei denn, Sie geben es explizit an, wenn Sie mithilfe von Stapelsemantik eine Zeichenfolge erstellen.

Eine Platform::String kann eingebettete NULL-Werte enthalten, jedoch nur, wenn die NULL ein Ergebnis eines Verkettungsvorgangs ist. Eingebettete NULLEN werden in Zeichenfolgenliteralen nicht unterstützt. Daher können Sie eingebettete NULLEN nicht in dieser Weise verwenden, um eine Platform::Stringzu initialisieren. Eingebettete NULL-Werte in einer Platform::String werden ignoriert, wenn die Zeichenfolge angezeigt wird, beispielsweise wenn sie einer TextBlock::Text -Eigenschaft zugewiesen ist. Eingebettete NULL-Werte werden entfernt, wenn der Zeichenfolgenwert von der Data -Eigenschaft zurückgegeben wird.

StringReference

In einigen Fällen empfängt Ihr Code (a) ein std::wstring- oder wchar_t string- oder L"-Zeichenfolgenliteral und übergibt ihn einfach an eine andere Methode, die einen String^ als Eingabeparameter akzeptiert. Solange der ursprüngliche Zeichenfolgenpuffer selbst gültig bleibt und nicht geändert wird, bevor die Funktion zurückgibt, können Sie die wchar_t* -Zeichenfolge oder das Zeichenfolgenliteral in Platform::StringReferencekonvertieren und dieses anstelle von Platform::String^übergeben. Dies ist zulässig, da StringReference über eine benutzerdefinierte Konvertierung zu Platform::String^verfügt. Mit StringReference können Sie vermeiden, dass eine zusätzliche Kopie der Zeichenfolgendaten erstellt wird. In Schleifen, in denen viele Zeichenfolgen übergeben werden, oder wenn sehr große Zeichenfolgen übergeben werden, können Sie mit StringReferenceeine deutliche Leistungsverbesserung erzielen. Aber, da StringReference im Grunde den ursprünglichen Zeichenfolgenpuffer verwendet, müssen Sie sorgfältig sein, um Speicherbeschädigungen zu vermeiden. Sie sollten StringReference nicht an eine asynchrone Methode übergeben, es sei denn, die ursprüngliche Zeichenfolge liegt garantiert im Bereich, wenn diese Methode zurückgibt. Ein String^, das von einem StringReference initialisiert wird, erzwingt eine Zuordnung und eine Kopie der Zeichenfolgendaten, wenn ein zweiter Zuweisungsvorgang auftritt. In diesem Fall verlieren Sie den Leistungsvorteil von StringReference.

Beachten Sie, dass StringReference ein Standard-C++-Klassentyp und keine Verweisklasse ist. Sie können ihn nicht für die öffentliche Schnittstelle von Verweisklassenverwenden, die Sie definieren.

Im folgenden Beispiel wird die Verwendung von StringReference veranschaulicht:

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
    }
}