Condividi tramite


Stringhe (C++/CX)

Il testo in Windows Runtime è rappresentato in C++/CX dalla classe Platform::String. Usare quando Platform::String Class si passano stringhe avanti e indietro ai metodi nelle classi di Windows Runtime o quando si interagisce con altri componenti di Windows Runtime attraverso il limite dell'interfaccia binaria dell'applicazione (ABI). L'oggetto Platform::String Class fornisce i metodi per numerose operazioni di stringa comuni ma non è progettato per essere una classe String completa. Nel modulo C++ utilizza i tipi di stringa C++ standard quali wstring per l'elaborazione dei testi importanti e converti il risultato finale in Platform::String^ prima di passarlo a o da un'interfaccia pubblica. La conversione tra wstring o wchar_t* e Platform::Stringè un'operazione semplice ed efficace.

Passaggio rapido

In alcuni casi, il compilatore verifica di poter creare un oggetto Platform::String o passare una classe String a una funzione in modo sicuro senza copiare i dati sottostanti in formato stringa. Tali operazioni sono note come passaggi rapidi e si svolgono in modo trasparente.

Costruzione di stringa

Il valore di un oggetto String è una sequenza (in sola lettura) non modificabile di caratteri char16 (Unicode a 16 bit). Poiché un oggetto String non è modificabile, l'assegnazione di un nuovo valore letterale stringa a una variabile String sostituisce effettivamente l'oggetto String originale con un nuovo oggetto String . Le operazioni di concatenazione implicano la distruzione dell'oggetto String originale e la creazione di uno nuovo.

Valori letterali

Un carattere letterale è un carattere racchiuso tra virgolette singole e una stringa letterale è una sequenza di caratteri racchiusa tra virgolette doppie. Se utilizzi un valore letterale per inizializzare una variabile String^, a livello di compilatore viene supposto che il valore letterale sia costituito da caratteri char16 . Ciò significa che non è necessario anteporre al valore letterale il modificatore di stringa "L" o racchiudere il valore letterale in una macro _T() o TEXT() . Per ulteriori informazioni sul supporto di C++ per Unicode, vedi Unicode Programming Summary.

Nell'esempio riportato di seguito sono mostrati vari modi per costruire oggetti 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());

Operazioni di gestione delle stringhe

La classe String fornisce i metodi e gli operatori per la concatenazione, il confronto di stringhe e altre operazioni di base sulle stringhe. Per eseguire modifiche di stringa più estese, utilizza la funzione membro String::Data() per recuperare il valore dell'oggetto String^ come const wchar_t*. Utilizza quindi tale valore per inizializzare un oggetto std::wstring, che fornisce funzioni avanzate di gestione delle stringhe.


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

Conversioni di stringhe

Platform::String può contenere solo caratteri char16 o il carattere NULL . Se l'applicazione deve usare caratteri a 8 bit, usare String::D ata per estrarre il testo come .const wchar_t* Puoi quindi utilizzare le funzioni di Windows o le funzioni di libreria standard appropriate per eseguire operazioni sui dati e convertirli di nuovo in wchar_t* o wstringda utilizzare per costruire un nuovo oggetto Platform::String.

Nel frammento di codice riportato di seguito viene illustrato come convertire una variabile String^ in o da una variabile wstring . Per ulteriori informazioni sulla gestione della stringa utilizzata in questo esempio, vedi 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() ); 

Valori di lunghezza della stringa e valore NULL incorporato

String ::Length restituisce il numero di caratteri nella stringa, non il numero di byte. Il carattere di terminazione NULL non viene contato a meno che tu non lo specifichi quando utilizzi la semantica dello stack per costruire una stringa.

Platform::String può contenere valori NULL, ma solo quando NULL è un risultato di un'operazione di concatenazione. I caratteri NULL incorporati non sono supportati nei valori letterali di stringa; pertanto, non li puoi utilizzare in quel modo per inizializzare un oggetto Platform::String. I valori NULL incorporati in Platform::String vengono ignorati nella visualizzazione della stringa, ad esempio, quando la stringa è assegnata a una proprietà TextBlock::Text . I caratteri NULL incorporati vengono rimossi quando il valore stringa viene restituito dalla proprietà Data .

StringReference

In alcuni casi il codice (a) riceve un valore letterale stringa std::wstring o wchar_t stringa o L"" e lo passa semplicemente a un altro metodo che accetta string^ come parametro di input. Finché lo stesso buffer di stringa originale rimane valido e non viene modificato prima della restituzione della funzione, puoi convertire la stringa o il valore letterale stringa wchar_t* in un valore Platform::StringReferencee passarlo al posto di Platform::String^. Ciò è consentito perché StringReference dispone di una conversione definita dall'utente in Platform::String^. Utilizzando StringReference puoi evitare di eseguire una copia aggiuntiva dei dati di tipo stringa. Nei cicli in cui passi un elevato numero di stringhe, o quando passi di dimensioni considerevoli, puoi ottenere un miglioramento significativo delle prestazioni utilizzando StringReference. Poiché tuttavia StringReference utilizza essenzialmente il buffer di stringa originale, devi prestare particolare attenzione per evitare il danneggiamento della memoria. Evita di passare StringReference a un metodo asincrono a meno di avere la certezza che la stringa originale sia nell'ambito quando viene restituito il metodo. Un parametro String^ inizializzato da StringReference forza un'allocazione e una copia dei dati di tipo stringa se si verifica una seconda operazione di assegnazione. In questo caso, perderai il vantaggio in termini di prestazioni di StringReference.

Tieni presente che StringReference è un tipo di classe C++ standard, non una classe di riferimento, quindi non puoi usarla nell'interfaccia pubblica delle classi di riferimento che definisci.

L'esempio seguente mostra come usare 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
    }
}