Chaînes (C++/CX)
Le texte dans Windows Runtime est représenté en C++/CX par la classe Platform ::String. Utilisez le Platform::String Class
moment où vous transmettez des chaînes à des méthodes dans des classes Windows Runtime, ou lorsque vous interagissez avec d’autres composants Windows Runtime dans la limite de l’interface binaire d’application (ABI). La Platform::String Class
fournit des méthodes pour plusieurs opérations de chaînes courantes mais elle n'est pas conçue pour être une classe de chaîne complète. Dans votre module C++, utilisez les types de chaînes C++ standard tels que wstring pour tout traitement de texte significatif, puis convertissez le résultat final en Platform::String^ avant de le passer vers ou à partir d'une interface publique. Il est facile et efficace de convertir entre wstring
ou wchar_t*
et Platform::String
.
Passage rapide
Dans certains cas, le compilateur peut vérifier qu'il peut sans risque construire une Platform::String
ou passer une String
à une fonction sans copier les données de chaîne sous-jacentes. Ces opérations sont appelées passage rapide et elles se produisent de façon transparente.
Construction de chaînes
La valeur d'un objet String
est une séquence (en lecture seule) immuable de caractères char16
(Unicode 16 bits). Étant donné qu'un objet String
est immuable, l'assignation d'un nouveau littéral de chaîne à une variable d' String
remplace en fait l'objet d'origine String
par un nouvel objet d' String
. Les opérations de concaténation impliquent la destruction de l'objet String
d'origine et la création d'un nouvel objet.
Littéraux
Un caractère littéral est un caractère placé entre guillemets simples et une chaîne littérale est une séquence de caractères placée entre guillemets doubles. Si vous utilisez un littéral pour initialiser une variable String^, le compilateur suppose que le littéral est constitué de caractères char16
. Ainsi, vous ne devez pas faire précéder le littéral par le modificateur de chaîne « L » ou le placer dans une macro _T() ou TEXT() . Pour plus d'informations sur la prise en charge de C++ pour Unicode, consultez Unicode Programming Summary.
L'exemple suivant montre différentes façons de construire des objets 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());
Opérations de gestion de chaînes
La classe String
fournit des méthodes et des opérateurs pour la concaténation et comparaison de chaînes et d'autres opérations de base sur les chaînes. Pour effectuer d'autres manipulations plus étendues sur les chaînes, utilisez la fonction membre String::Data()
pour récupérer la valeur de l'objet String^
sous forme de const wchar_t*
. Utilisez ensuite cette valeur pour initialiser un std::wstring
, qui fournit des fonctions de gestion de chaînes évoluées.
// 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];
Conversions de chaînes
Une Platform::String
ne peut contenir que des caractères char16
ou le caractère NULL
. Si votre application doit utiliser des caractères 8 bits, utilisez string ::D ata pour extraire le texte en tant que const wchar_t*
. Vous pouvez ensuite utiliser les fonctions Windows appropriées ou les fonctions de bibliothèque standard pour traiter les données et les reconvertir en un wchar_t*
ou wstring, que vous pouvez utiliser pour construire une nouvelle Platform::String
.
Le fragment de code suivant montre comment convertir une variable String^
vers et à partir d'une variable wstring
. Pour plus d'informations sur la manipulation de chaînes utilisée dans cet exemple, consultez 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() );
Longueur de chaîne et valeurs NULL incorporées
String ::Length retourne le nombre de caractères dans la chaîne, et non le nombre d’octets. Le caractère NULL de fin n'est pas compté, sauf si vous le spécifiez explicitement lorsque vous utilisez la sémantique de pile pour construire une chaîne.
Une Platform::String
peut contenir des valeurs NULL incorporées, mais uniquement lorsque NULL est le résultat d'une opération de concaténation. Les valeurs NULL incorporées ne sont pas prises en charge dans les littéraux de chaîne. Par conséquent, vous ne pouvez pas utiliser de valeurs NULL incorporées de cette manière pour initialiser une Platform::String
. Les valeurs NULL incorporées dans une Platform::String
sont ignorées lorsque la chaîne est affichée, par exemple lorsqu'elle est assignée à une propriété TextBlock::Text
. Les valeurs NULL incorporées sont supprimées quand la valeur de chaîne est retournée par la propriété Data
.
StringReference
Dans certains cas, votre code (a) reçoit un std ::wstring, ou wchar_t littéral de chaîne ou L" » et le transmet simplement à une autre méthode qui prend une chaîne^ comme paramètre d’entrée. Tant que la mémoire tampon de chaîne d'origine elle-même reste valide et qu'elle ne mute pas avant le retour de la fonction, vous pouvez convertir la chaîne ou le littéral de chaîne wchar_t*
en Platform::StringReference, et le passer à la place de Platform::String^
. Cela est autorisé, car StringReference
dispose d'une conversion définie par l'utilisateur en Platform::String^
. À l'aide de StringReference
, vous pouvez éviter d'effectuer une copie supplémentaire des données de chaîne. Dans les boucles où vous passez un grand nombre de chaînes, ou lorsque vous passez des chaînes de très grande taille, vous pouvez éventuellement obtenir une amélioration significative des performances à l'aide de StringReference
. Toutefois, dans la mesure où StringReference
emprunte essentiellement la mémoire tampon de chaîne d'origine, vous devez faire preuve d'une grande vigilance afin d'éviter une altération de la mémoire. Ne passez pas StringReference
à une méthode asynchrone, à moins que la chaîne d'origine ne soit dans la portée lorsque cette méthode est retournée. Un String^ initialisé à partir de StringReference force l'allocation et la copie des données de chaîne, si une seconde opération d'affectation se produit. Dans ce cas, vous perdez le gain de performances fourni par StringReference
.
Notez que StringReference
est un type de classe C++ standard, et non une classe ref. Vous ne pouvez pas l'utiliser dans l'interface publique des classes ref que vous définissez.
L'exemple suivant montre comment utiliser 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
}
}