Cadeias de caracteres (C++/CX)

O texto no Windows Runtime é representado em C++/CX pela Classe Platform::String. Use Platform::String Class ao passar cadeias de caracteres de e para métodos nas classes do Windows Runtime ou quando você estiver interagindo com outros componentes do Windows Runtime nos limites da ABI (interface binária de aplicativo). Platform::String Class fornece métodos para várias operações comuns de cadeia de caracteres, mas não foi projetado para ser uma classe de cadeia de caracteres completa. Em seu módulo C++, use tipos de cadeia de caracteres C++ padrão, como wstring para qualquer processamento de texto significativo e, em seguida, converta o resultado final em Platform::String^ antes de transmiti-lo de ou para uma interface pública. A conversão entre wstring ou wchar_t* e Platform::Stringé fácil e eficiente.

Passagem rápida

Em alguns casos, o compilador pode verificar se pode construir com segurança uma Platform::String ou passar uma String a uma função sem copiar os dados da cadeia de caracteres subjacente. Essas operações são conhecidas como passagens rápidas e ocorrem de modo transparente.

Construção da cadeia de caracteres

O valor de um objeto String é uma sequência imutável (somente leitura) de caracteres char16 (Unicode de 16 bits). Como um objeto String é imutável, a atribuição de uma nova cadeia de caracteres literal a uma variável String na verdade substitui o objeto String original por um novo objeto String . As operações de concatenação envolvem a destruição do objeto String original e a criação de um novo objeto.

Literais

Um caractere literal é um caractere colocado entre aspas simples e uma cadeia de caracteres literal é uma sequência de caractere colocada entre aspas duplas. Se você usar um literal para inicializar uma variável String^, o compilador assumirá que o literal consiste em caracteres char16 . Ou seja, você não tem que preceder o literal com o modificador de cadeia de caracteres 'L', nem colocar o literal em uma macro _T() ou TEXT() . Para obter mais informações sobre o suporte do C++ para Unicode, consulte Unicode Programming Summary.

O exemplo a seguir mostra várias maneiras de construir objetos 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());

Operações de manipulação de cadeia de caracteres

A classe String fornece métodos e operadores para concatenação, cadeias de caracteres de comparação e outras operações básicas de cadeia de caracteres. Para executar manipulações de cadeia de caracteres mais extensivas, use a função de membro String::Data() para recuperar o valor do objeto String^ como um const wchar_t*. Em seguida, use esse valor para inicializar std::wstring, que fornece ricas funções de manipulação de cadeia de caracteres.


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

Conversões de cadeia de caracteres

Uma Platform::String pode conter apenas caracteres char16 ou o caractere NULL . Se seu aplicativo tiver de funcionar com caracteres de 8 bits, use String::Data para extrair o texto como const wchar_t*. Você pode usar as funções apropriadas do Windows ou as funções de Biblioteca Padrão para operar nos dados e convertê-los novamente em wchar_t* ou wstring, que poderá usar para construir uma nova Platform::String.

O fragmento de código a seguir mostra como converter uma variável String^ de e em uma variável wstring . Para obter mais informações sobre a manipulação de cadeia de caracteres usada nesse exemplo, consulte 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() ); 

Valores de comprimento da cadeia de caracteres e NULL inserido

O String::Length retorna o número de caracteres na cadeia de caracteres, não o número de bytes. O caractere NULL de terminação não é contado, a menos que você o especifique explicitamente ao usar semântica de pilha para construir uma cadeia de caracteres.

Uma Platform::String pode conter valores NULL inseridos, mas somente quando o NULL for o resultado de uma operação de concatenação. Não há suporte para NULLs inseridos em cadeias de caracteres literais; portanto, você não pode usar NULLs inseridos nessa questão para inicializar Platform::String. Os valores NULL inseridos em uma Platform::String são ignorados quando a cadeia de caracteres é exibida, por exemplo, quando é atribuída a uma propriedade TextBlock::Text . NULLs inseridos são removidos quando o valor da cadeia de caracteres é retornado pela propriedade Data .

StringReference

Em alguns casos, seu código (a) recebe uma cadeia de caracteres std::wstring ou wchar_t ou um literal de cadeia de caracteres L"" e apenas os transmite para outro método que utiliza String^ como parâmetro de entrada. Contanto que o buffer da cadeia de caracteres original em si permaneça válido e não seja modificado antes de a função retornar, você pode converter a cadeia de caracteres wchar_t* ou o literal da cadeia de caracteres em Platform::StringReferencee transmiti-lo em vez de Platform::String^. Isso é permitido porque StringReference tem uma conversão definida pelo usuário para Platform::String^. Usando StringReference , você pode evitar a necessidade de fazer uma cópia extra dos dados da cadeia de caracteres. Em loops em que você estiver transmitindo uma grande quantidade de cadeias de caracteres, ou ao transmitir cadeias de caracteres muito grandes, você poderá obter uma melhoria significativa de desempenho usando StringReference. Mas como StringReference essencialmente pega emprestado o buffer da cadeia de caracteres original, você deve ter extremo cuidado para evitar danos à memória. Você não deve transmitir StringReference a um método assíncrono a menos que a cadeia de caracteres original faça parte do escopo quando esse método retornar. Uma String^ inicializada a partir de uma StringReference forçará uma alocação e uma cópia dos dados da cadeia de caracteres se uma segunda operação de atribuição ocorrer. Nesse caso, você perderá o benefício de desempenho da StringReference.

Observe que StringReference é um tipo de classe C++ padrão, não uma classe ref, e não é possível usá-la na interface pública das classes ref que você definir.

O exemplo a seguir mostra como usar 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
    }
}