Buscar..


Introducción

Las cadenas son objetos que representan secuencias de caracteres. El estándar string clase proporciona una alternativa sencilla, segura y versátil para la utilización de matrices explícitas de char s cuando se trata de texto y otras secuencias de caracteres. La clase de string C ++ es parte del std nombres estándar y se estandarizó en 1998.

Sintaxis

  • // declaración de cadena vacía

    std :: string s;

  • // Construyendo desde const char * (c-string)

    std :: string s ("Hello");

    std :: string s = "Hello";

  • // Construyendo usando el constructor de copia

    std :: string s1 ("Hello");

    std :: string s2 (s1);

  • // Construyendo a partir de subcadenas

    std :: string s1 ("Hello");

    std :: string s2 (s1, 0, 4); // Copia 4 caracteres de la posición 0 de s1 en s2

  • // Construyendo desde un buffer de personajes.

    std :: string s1 ("Hello World");
    std :: string s2 (s1, 5); // Copia los primeros 5 caracteres de s1 en s2

  • // Construir usando constructor de relleno (solo char)

    std :: string s (5, 'a'); // s contiene aaaaa

  • // Construir usando el constructor de rango e iterador

    std :: string s1 ("Hello World");

    std :: string s2 (s1.begin (), s1.begin () + 5); // Copia los primeros 5 caracteres de s1 en s2

Observaciones

Antes de usar std::string , debe incluir la string del encabezado, ya que incluye funciones / operadores / sobrecargas que otros encabezados (por ejemplo, iostream ) no incluyen.


El uso de const char * constructor con un nullptr conduce a un comportamiento indefinido.

std::string oops(nullptr);
std::cout << oops << "\n";

El método at lanza un std::out_of_range excepción si index >= size() .

El comportamiento del operator[] es un poco más complicado, en todos los casos tiene un comportamiento indefinido si index > size() , pero cuando index == size() :

C ++ 11
  1. En una cadena no constante, el comportamiento no está definido ;
  2. En una cadena constante, se devuelve una referencia a un carácter con valor CharT() (el carácter nulo ).
C ++ 11
  1. Se CharT() una referencia a un carácter con valor CharT() (el carácter nulo ).
  2. Modificar esta referencia es un comportamiento indefinido .

Como C ++ 14, en lugar de usar "foo" , se recomienda usar "foo"s , ya que s es un sufijo literal definido por el usuario , que convierte el const char* "foo" en std::string "foo" .

Nota: tienes que usar el espacio de nombres std::string_literals o std::literals std::string_literals para obtener el s literal.

Terrible

Usa std::string::substr para dividir una cadena. Hay dos variantes de esta función miembro.

La primera toma una posición inicial desde la cual debe comenzar la subcadena devuelta. La posición inicial debe ser válida en el rango (0, str.length()] :

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(11); // "bar and world!"

El segundo toma una posición inicial y una longitud total de la nueva subcadena. Independientemente de la longitud , la subcadena nunca pasará del final de la cadena de origen:

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(15, 3); // "and"

Tenga en cuenta que también puede llamar a substr sin argumentos, en este caso se devuelve una copia exacta de la cadena

std::string str = "Hello foo, bar and world!";
std::string newstr = str.substr(); // "Hello foo, bar and world!"

Reemplazo de cuerdas

Reemplazar por posición

Para reemplazar una porción de una std::string puede usar el método replace de la std::string .

replace tiene una gran cantidad de sobrecargas útiles:

//Define string
std::string str = "Hello foo, bar and world!";
std::string alternate = "Hello foobar";

//1)
str.replace(6, 3, "bar"); //"Hello bar, bar and world!"

//2)
str.replace(str.begin() + 6, str.end(), "nobody!"); //"Hello nobody!"

//3)
str.replace(19, 5, alternate, 6, 6); //"Hello foo, bar and foobar!"
C ++ 14
//4)
str.replace(19, 5, alternate, 6); //"Hello foo, bar and foobar!"
//5)
str.replace(str.begin(), str.begin() + 5, str.begin() + 6, str.begin() + 9);
//"foo foo, bar and world!"

//6)
str.replace(0, 5, 3, 'z'); //"zzz foo, bar and world!"

//7)
str.replace(str.begin() + 6, str.begin() + 9, 3, 'x'); //"Hello xxx, bar and world!"
C ++ 11
//8)
str.replace(str.begin(), str.begin() + 5, { 'x', 'y', 'z' }); //"xyz foo, bar and world!"

Reemplazar las ocurrencias de una cadena con otra cadena

Reemplace solo la primera vez que se replace con with en str :

std::string replaceString(std::string str,
                          const std::string& replace,
                          const std::string& with){
    std::size_t pos = str.find(replace);
    if (pos != std::string::npos)
        str.replace(pos, replace.length(), with);
    return str;
}

Reemplace todas las ocurrencias de replace con with en str :

std::string replaceStringAll(std::string str,
                             const std::string& replace,
                             const std::string& with) {
    if(!replace.empty()) {
        std::size_t pos = 0;
        while ((pos = str.find(replace, pos)) != std::string::npos) {
            str.replace(pos, replace.length(), with);
            pos += with.length();
        }
    }
    return str;
}

Concatenación

Puede concatenar std::string s utilizando los operadores sobrecargados + y += . Usando el operador + :

std::string hello = "Hello";
std::string world = "world";
std::string helloworld = hello + world; // "Helloworld"

Usando el operador += :

std::string hello = "Hello";
std::string world = "world";
hello += world; // "Helloworld"

También puede agregar cadenas C, incluidos los literales de cadena:

std::string hello = "Hello";
std::string world = "world";
const char *comma = ", ";
std::string newhelloworld = hello + comma + world + "!"; // "Hello, world!"

También puede utilizar push_back() para hacer retroceder individuo char s:

std::string s = "a, b, ";
s.push_back('c'); // "a, b, c"

También hay append() , que es bastante parecido a += :

std::string app = "test and ";
app.append("test"); // "test and test"

Accediendo a un personaje

Hay varias formas de extraer caracteres de una std::string y cada una es sutilmente diferente.

std::string str("Hello world!");

operador [] (n)

Devuelve una referencia al carácter en el índice n.

std::string::operator[] no está verificada por límites y no lanza una excepción. La persona que llama es responsable de afirmar que el índice está dentro del rango de la cadena:

char c = str[6]; // 'w'

en (n)

Devuelve una referencia al carácter en el índice n.

std::string::at es los límites std::out_of_range , y lanzará std::out_of_range si el índice no está dentro del rango de la cadena:

char c = str.at(7); // 'o'
C ++ 11

Nota: Ambos ejemplos darán como resultado un comportamiento indefinido si la cadena está vacía.


frente()

Devuelve una referencia al primer carácter:

char c = str.front(); // 'H'

atrás()

Devuelve una referencia al último carácter:

char c = str.back(); // '!'

Tokenizar

Listado de menos costoso a más costoso en tiempo de ejecución:

  1. str::strtok es el método de tokenización estándar más barato, también permite que el delimitador se modifique entre tokens, pero incurre en 3 dificultades con C ++ moderno:

    • std::strtok no se puede usar en varias strings al mismo tiempo (aunque algunas implementaciones se extienden para admitir esto, como: strtok_s )
    • Por la misma razón, std::strtok no se puede usar en varios subprocesos simultáneamente (sin embargo, esto puede ser definido por la implementación, por ejemplo: la implementación de Visual Studio es segura para subprocesos )
    • Al llamar a std::strtok modifica la std::string que está funcionando, por lo que no se puede usar en const string const char* , caracteres const char* o cadenas literales, para señalizar cualquiera de ellas con std::strtok o para operar en una std::string cuyo contenido debe conservarse, la entrada debería copiarse, luego la copia podría operarse

    En general, cualquiera de estas opciones de costo estará oculto en el costo de asignación de los tokens, pero si se requiere el algoritmo más barato y las dificultades de std::strtok strtok no se pueden superar, considere una solución manual .

// String to tokenize
std::string str{ "The quick brown fox" };
// Vector to store tokens
vector<std::string> tokens;

for (auto i = strtok(&str[0], " "); i != NULL; i = strtok(NULL, " "))
    tokens.push_back(i);

Ejemplo vivo

  1. std::istream_iterator usa el operador de extracción del flujo de forma iterativa. Si la entrada std::string está delimitada por espacios en blanco, esto es capaz de expandirse en la opción std::strtok eliminando sus dificultades, permitiendo la tokenización en línea, lo que permite la generación de un const vector<string> , y agregando soporte para múltiples delimitando caracteres de espacio en blanco:
// String to tokenize
const std::string str("The  quick \tbrown \nfox");
std::istringstream is(str);
// Vector to store tokens
const std::vector<std::string> tokens = std::vector<std::string>(
                                        std::istream_iterator<std::string>(is),
                                        std::istream_iterator<std::string>());

Ejemplo vivo

  1. El std::regex_token_iterator utiliza un std::regex para tokenizar iterativamente. Proporciona una definición de delimitador más flexible. Por ejemplo, comas no delimitadas y espacios en blanco:
C ++ 11
// String to tokenize
const std::string str{ "The ,qu\\,ick ,\tbrown, fox" };
const std::regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
// Vector to store tokens
const std::vector<std::string> tokens{ 
    std::sregex_token_iterator(str.begin(), str.end(), re, 1), 
    std::sregex_token_iterator() 
};

Ejemplo vivo

Vea el ejemplo regex_token_iterator para más detalles.

Conversión a (const) char *

Para obtener acceso const char* a los datos de un std::string , puede usar la función miembro c_str() del string. Tenga en cuenta que el puntero solo es válido mientras el objeto std::string esté dentro del alcance y permanezca sin cambios, lo que significa que solo se puede llamar a los métodos const en el objeto.

C ++ 17

La función miembro de data() se puede usar para obtener un char* modificable, que se puede usar para manipular los datos del objeto std::string .

C ++ 11

También se puede obtener un char* modificable tomando la dirección del primer carácter: &s[0] . En C ++ 11, se garantiza que esto produce una cadena bien formada, terminada en nulo. Tenga en cuenta que &s[0] está bien formado incluso si s está vacío, mientras que &s.front() no está definido si s está vacío.

C ++ 11
std::string str("This is a string.");
const char* cstr = str.c_str(); // cstr points to: "This is a string.\0"
const char* data = str.data();  // data points to: "This is a string.\0"
std::string str("This is a string.");

// Copy the contents of str to untie lifetime from the std::string object
std::unique_ptr<char []> cstr = std::make_unique<char[]>(str.size() + 1);

// Alternative to the line above (no exception safety):
// char* cstr_unsafe = new char[str.size() + 1];

std::copy(str.data(), str.data() + str.size(), cstr);
cstr[str.size()] = '\0'; // A null-terminator needs to be added

// delete[] cstr_unsafe;
std::cout << cstr.get();

Encontrar caracteres en una cadena

Para encontrar un carácter u otra cadena, puede usar std::string::find . Devuelve la posición del primer carácter de la primera partida. Si no se encontraron coincidencias, la función devuelve std::string::npos

std::string str = "Curiosity killed the cat";
auto it = str.find("cat");

if (it != std::string::npos)
    std::cout << "Found at position: " << it << '\n';
else
    std::cout << "Not found!\n";

Encontrado en la posición: 21


Las oportunidades de búsqueda se amplían aún más por las siguientes funciones:

find_first_of     // Find first occurrence of characters 
find_first_not_of // Find first absence of characters 
find_last_of      // Find last occurrence of characters 
find_last_not_of  // Find last absence of characters 

Estas funciones pueden permitirle buscar caracteres desde el final de la cadena, así como encontrar el caso negativo (es decir, los caracteres que no están en la cadena). Aquí hay un ejemplo:

std::string str = "dog dog cat cat";
std::cout << "Found at position: " << str.find_last_of("gzx") << '\n';

Encontrado en la posición: 6

Nota: tenga en cuenta que las funciones anteriores no buscan subcadenas, sino caracteres contenidos en la cadena de búsqueda. En este caso, la última aparición de 'g' se encontró en la posición 6 (los otros caracteres no se encontraron).

Recorte de caracteres al inicio / final

Este ejemplo requiere los encabezados <algorithm> , <locale> y <utility> .

C ++ 11

Recortar una secuencia o cadena significa eliminar todos los elementos (o caracteres) iniciales y finales que coinciden con un determinado predicado. Primero recortamos los elementos finales, porque no implica mover ningún elemento, y luego recortamos los elementos iniciales. Tenga en cuenta que las generalizaciones siguientes funcionan para todos los tipos de std::basic_string (por ejemplo, std::string y std::wstring ), y accidentalmente también para contenedores de secuencias (por ejemplo, std::vector y std::list ).

template <typename Sequence, // any basic_string, vector, list etc.
          typename Pred>     // a predicate on the element (character) type
Sequence& trim(Sequence& seq, Pred pred) {
    return trim_start(trim_end(seq, pred), pred);
}

Recortar los elementos finales implica encontrar el último elemento que no coincide con el predicado y borrar de allí en adelante:

template <typename Sequence, typename Pred>
Sequence& trim_end(Sequence& seq, Pred pred) {
    auto last = std::find_if_not(seq.rbegin(),
                                 seq.rend(),
                                 pred);
    seq.erase(last.base(), seq.end());
    return seq;
}

Recortar los elementos iniciales implica encontrar el primer elemento que no coincide con el predicado y borrar hasta allí:

template <typename Sequence, typename Pred>
Sequence& trim_start(Sequence& seq, Pred pred) {
    auto first = std::find_if_not(seq.begin(),
                                  seq.end(),
                                  pred);
    seq.erase(seq.begin(), first);
    return seq;
}

Para especializar lo anterior para recortar espacios en blanco en una std::string std::isspace() podemos usar la función std::isspace() como predicado:

std::string& trim(std::string& str, const std::locale& loc = std::locale()) {
    return trim(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_start(std::string& str, const std::locale& loc = std::locale()) {
    return trim_start(str, [&loc](const char c){ return std::isspace(c, loc); });
}

std::string& trim_end(std::string& str, const std::locale& loc = std::locale()) {
    return trim_end(str, [&loc](const char c){ return std::isspace(c, loc); });
}

De manera similar, podemos usar la función std::iswspace() para std::wstring etc.

Si desea crear una nueva secuencia que sea una copia recortada, puede usar una función separada:

template <typename Sequence, typename Pred>
Sequence trim_copy(Sequence seq, Pred pred) { // NOTE: passing seq by value
    trim(seq, pred);
    return seq;
}

Comparacion lexicografica

Dos std::string s se pueden comparar lexicográficamente usando los operadores == != , < , <= , > Y >= :

std::string str1 = "Foo";
std::string str2 = "Bar";

assert(!(str1 < str2));
assert(str > str2);
assert(!(str1 <= str2));
assert(str1 >= str2);
assert(!(str1 == str2));
assert(str1 != str2);

Todas estas funciones utilizan el método std::string::compare() subyacente para realizar la comparación, y devuelven por conveniencia valores booleanos. El funcionamiento de estas funciones se puede interpretar de la siguiente manera, independientemente de la implementación real:

  • operador == :

    Si str1.length() == str2.length() y cada par de caracteres coinciden, devuelve true , de lo contrario devuelve false .

  • operador != :

    Si str1.length() != str2.length() o un par de caracteres no coincide, devuelve true , de lo contrario, devuelve false .

  • operador < u operador > :

    Busca el primer par de caracteres diferentes, los compara y luego devuelve el resultado booleano.

  • operador <= u operador >= :

    Busca el primer par de caracteres diferentes, los compara y luego devuelve el resultado booleano.

Nota: el término par de caracteres significa los caracteres correspondientes en ambas cadenas de las mismas posiciones. Para una mejor comprensión, si dos cadenas de ejemplo son str1 y str2 , y sus longitudes son n y m respectivamente, entonces los pares de caracteres de ambas cadenas significan cada par str1[i] y str2[i] donde i = 0, 1, 2,. .., max (n, m) . Si por alguna donde no existe i el carácter correspondiente, es decir, cuando i es mayor o igual a n o m , sería considerado como el valor más bajo.


Aquí hay un ejemplo del uso de < :

std::string str1 = "Barr";
std::string str2 = "Bar";

assert(str2 < str1);

Los pasos son los siguientes:

  1. Compara los primeros caracteres, 'B' == 'B' - sigue adelante.
  2. Compara los segundos caracteres, 'a' == 'a' - sigue adelante.
  3. Compara los terceros caracteres, 'r' == 'r' - sigue adelante.
  4. El rango str2 ahora está agotado, mientras que el rango str1 aún tiene caracteres. Así, str2 < str1 .

Conversión a std :: wstring

En C ++, las secuencias de caracteres se representan especializando la clase std::basic_string con un tipo de carácter nativo. Las dos colecciones principales definidas por la biblioteca estándar son std::string y std::wstring :

  • std::string está construido con elementos de tipo char

  • std::wstring está construido con elementos de tipo wchar_t

Para convertir entre los dos tipos, use wstring_convert :

#include <string>
#include <codecvt>
#include <locale>

std::string input_str = "this is a -string-, which is a sequence based on the -char- type.";
std::wstring input_wstr = L"this is a -wide- string, which is based on the -wchar_t- type.";

// conversion
std::wstring str_turned_to_wstr = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(input_str);

std::string wstr_turned_to_str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(input_wstr);

Para mejorar la facilidad de uso y / o la legibilidad, puede definir funciones para realizar la conversión:

#include <string>
#include <codecvt>
#include <locale>

using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;

std::string to_string(std::wstring wstr)
{
    return strconverter.to_bytes(wstr);
}

std::wstring to_wstring(std::string str)
{
    return strconverter.from_bytes(str);
}

Uso de la muestra:

std::wstring a_wide_string = to_wstring("Hello World!");

Eso es ciertamente más legible que std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("Hello World!") .


Tenga en cuenta que char y wchar_t no implican codificación, y no da ninguna indicación de tamaño en bytes. Por ejemplo, wchar_t se implementa comúnmente como un tipo de datos de 2 bytes y generalmente contiene datos codificados en UTF-16 en Windows (o UCS-2 en versiones anteriores a Windows 2000) y como un tipo de datos de 4 bytes codificados en UTF-32 en Linux Esto contrasta con los tipos más nuevos char16_t y char32_t , que se introdujeron en C ++ 11 y se garantiza que son lo suficientemente grandes como para contener cualquier "carácter" UTF16 o UTF32 (o, más precisamente, el punto de código ) respectivamente.

Usando la clase std :: string_view

C ++ 17

C ++ 17 introduce std::string_view , que es simplemente un rango no propietario de caracteres const char , implementable como un par de punteros o un puntero y una longitud. Es un tipo de parámetro superior para funciones que requieren datos de cadena no modificables. Antes de C ++ 17, había tres opciones para esto:

void foo(std::string const& s);      // pre-C++17, single argument, could incur
                                     // allocation if caller's data was not in a string
                                     // (e.g. string literal or vector<char> )

void foo(const char* s, size_t len); // pre-C++17, two arguments, have to pass them
                                     // both everywhere

void foo(const char* s);             // pre-C++17, single argument, but need to call
                                     // strlen()

template <class StringT>
void foo(StringT const& s);          // pre-C++17, caller can pass arbitrary char data
                                     // provider, but now foo() has to live in a header

Todos estos pueden ser reemplazados por:

void foo(std::string_view s);        // post-C++17, single argument, tighter coupling
                                     // zero copies regardless of how caller is storing
                                     // the data

Tenga en cuenta que std::string_view no puede modificar sus datos subyacentes .

string_view es útil cuando quiere evitar copias innecesarias.

Ofrece un subconjunto útil de la funcionalidad que hace std::string , aunque algunas de las funciones se comportan de manera diferente:

std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; //A really long string

//Bad way - 'string::substr' returns a new string (expensive if the string is long)
std::cout << str.substr(15, 10) << '\n';

//Good way - No copies are created!
std::string_view view = str;

// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';

Recorriendo cada personaje

C ++ 11

std::string admite iteradores, por lo que puede utilizar un bucle basado en rangos para recorrer cada carácter:

std::string str = "Hello World!";
for (auto c : str)
    std::cout << c;

Puedes usar un bucle tradicional for cada bucle:

std::string str = "Hello World!";
for (std::size_t i = 0; i < str.length(); ++i)
    std::cout << str[i];

Conversión a enteros / tipos de punto flotante

Una std::string contiene un número se puede convertir en un tipo entero, o un tipo de punto flotante, usando funciones de conversión.

Tenga en cuenta que todas estas funciones dejan de analizar la cadena de entrada tan pronto como encuentran un carácter no numérico, por lo que "123abc" se convertirá en 123 .


La familia de funciones std::ato* convierte cadenas de estilo C (matrices de caracteres) en tipos enteros o de punto flotante:

std::string ten = "10";

double num1 = std::atof(ten.c_str());
int num2 = std::atoi(ten.c_str());
long num3 = std::atol(ten.c_str());
C ++ 11
long long num4 = std::atoll(ten.c_str());

Sin embargo, se desaconseja el uso de estas funciones porque devuelven 0 si no pueden analizar la cadena. Esto es malo porque 0 también podría ser un resultado válido, si, por ejemplo, la cadena de entrada era "0", por lo que es imposible determinar si la conversión realmente falló.

La nueva familia de funciones std::sto* convierte std::string s en tipos enteros o de punto flotante, y lanza excepciones si no pueden analizar su entrada. Deberías usar estas funciones si es posible :

C ++ 11
std::string ten = "10";

int num1 = std::stoi(ten);
long num2 = std::stol(ten);
long long num3 = std::stoll(ten);

float num4 = std::stof(ten);
double num5 = std::stod(ten);
long double num6 = std::stold(ten);

Además, estas funciones también manejan cadenas octales y hexagonales a diferencia de la familia std::ato* . El segundo parámetro es un puntero al primer carácter no convertido en la cadena de entrada (no ilustrado aquí), y el tercer parámetro es la base a utilizar. 0 es la detección automática de octal (comenzando con 0 ) y hexadecimal (comenzando con 0x o 0X ), y cualquier otro valor es la base para usar

std::string ten = "10";
std::string ten_octal = "12";
std::string ten_hex = "0xA";

int num1 = std::stoi(ten, 0, 2); // Returns 2
int num2 = std::stoi(ten_octal, 0, 8); // Returns 10
long num3 = std::stol(ten_hex, 0, 16);  // Returns 10
long num4 = std::stol(ten_hex);  // Returns 0
long num5 = std::stol(ten_hex, 0, 0); // Returns 10 as it detects the leading 0x

Convertir entre codificaciones de caracteres.

La conversión entre codificaciones es fácil con C ++ 11 y la mayoría de los compiladores pueden tratarla de forma multiplataforma a través de los <codecvt> y <locale> .

#include <iostream>
#include <codecvt>
#include <locale>
#include <string>
using namespace std;

int main() {
    // converts between wstring and utf8 string
    wstring_convert<codecvt_utf8_utf16<wchar_t>> wchar_to_utf8;
    // converts between u16string and utf8 string
    wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> utf16_to_utf8;
    
    wstring wstr = L"foobar";
    string utf8str = wchar_to_utf8.to_bytes(wstr);
    wstring wstr2 = wchar_to_utf8.from_bytes(utf8str);
    
    wcout << wstr << endl;
    cout << utf8str << endl;
    wcout << wstr2 << endl;
    
    u16string u16str = u"foobar";
    string utf8str2 = utf16_to_utf8.to_bytes(u16str);
    u16string u16str2 = utf16_to_utf8.from_bytes(utf8str2);
    
    return 0;
}

Tenga en cuenta que Visual Studio 2015 proporciona soporte para estas conversiones, pero un error en la implementación de su biblioteca requiere el uso de una plantilla diferente para wstring_convert cuando se trata de char16_t :

using utf16_char = unsigned short;
wstring_convert<codecvt_utf8_utf16<utf16_char>, utf16_char> conv_utf8_utf16;

void strings::utf16_to_utf8(const std::u16string& utf16, std::string& utf8)
{
  std::basic_string<utf16_char> tmp;
  tmp.resize(utf16.length());
  std::copy(utf16.begin(), utf16.end(), tmp.begin());
  utf8 = conv_utf8_utf16.to_bytes(tmp);
}
void strings::utf8_to_utf16(const std::string& utf8, std::u16string& utf16)
{ 
  std::basic_string<utf16_char> tmp = conv_utf8_utf16.from_bytes(utf8);
  utf16.clear();
  utf16.resize(tmp.length());
  std::copy(tmp.begin(), tmp.end(), utf16.begin());
}

Comprobando si una cadena es un prefijo de otra

C ++ 14

En C ++ 14, esto se hace fácilmente mediante std::mismatch que devuelve el primer par no coincidente de dos rangos:

std::string prefix = "foo";
std::string string = "foobar";

bool isPrefix = std::mismatch(prefix.begin(), prefix.end(),
    string.begin(), string.end()).first == prefix.end();

Tenga en cuenta que existía una versión con rango y medio de mismatch() anterior a C ++ 14, pero esto no es seguro en el caso de que la segunda cadena sea la más corta de las dos.

C ++ 14

Todavía podemos usar la versión de rango y medio de std::mismatch() , pero primero debemos verificar que la primera cadena sea tan grande como la segunda:

bool isPrefix = prefix.size() <= string.size() &&
    std::mismatch(prefix.begin(), prefix.end(),
        string.begin(), string.end()).first == prefix.end();
C ++ 17

Con std::string_view , podemos escribir la comparación directa que queremos sin tener que preocuparnos por la sobrecarga de asignación o hacer copias:

bool isPrefix(std::string_view prefix, std::string_view full)
{
    return prefix == full.substr(0, prefix.size());
}

Convertir a std :: string

std::ostringstream se puede utilizar para convertir cualquier tipo transmitible en una representación de cadena, insertando el objeto en un objeto std::ostringstream (con el operador de inserción de flujo << ) y luego convirtiendo el std::ostringstream en un std::string .

Por ejemplo, int :

#include <sstream>

int main()
{
    int val = 4;
    std::ostringstream str;
    str << val;
    std::string converted = str.str();
    return 0;
}

Escribiendo tu propia función de conversión, la simple:

template<class T>
std::string toString(const T& x)
{
  std::ostringstream ss;
  ss << x;
  return ss.str();
}

funciona pero no es adecuado para el código crítico de rendimiento.

Las clases definidas por el usuario pueden implementar el operador de inserción de flujo si lo desea:

std::ostream operator<<( std::ostream& out, const A& a )
{
    // write a string representation of a to out
    return out; 
}
C ++ 11

Aparte de las secuencias, desde C ++ 11 también puede usar la función std::to_string (y std::to_wstring ) que está sobrecargada para todos los tipos fundamentales y devuelve la representación de cadena de su parámetro.

std::string s = to_string(0x12f3);  // after this the string s contains "4851"


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow