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