Saltar a contenido

Última actualización:2026-10-12

Análisis profundo de STL string

Cuando usamos C++, conocemos bastante bien los fundamentos de la biblioteca , en particular std::string, que se emplea para crear cadenas en C++. Sin duda es una mejora sobre las antiguas «cadenas» de estilo C (arrays de caracteres terminados en el carácter nulo). Sin embargo, la biblioteca estándar de C++ introdujo en C++17 y C++20 componentes más útiles que pueden ayudarte a escribir código más eficiente.

En el archivo de cabecera , la clase std::basic_string es una clase plantilla que ofrece especializaciones para diversos tipos de cadena, incluidas std::string para las cadenas habituales (es decir, std::basic_string) y std::wstring para las cadenas anchas (es decir, std::basic_string).

También existen cadenas específicas de anchura fija, como std::u32string (es decir, std::basic_string) y std::u16string (es decir, std::basic_string).

En C++20 se introdujo char8_t, lo que trajo consigo std::u8string (es decir, std::basic_string). No sé por qué hubo que esperar hasta C++20 para introducir char8_t, así que planteo una pregunta: ¿en qué estándar existen char16_t y char32_t? Nos vemos en los comentarios

C++11

Bajo el estándar C++11, el manejo de cadenas dependía principalmente de la clase std::string, una clase de cadena con asignación dinámica de memoria. Además, se introdujeron nuevos tipos de cadena de anchura fija, como std::u32string y std::u16string, que aportaron mejor soporte para el manejo de caracteres Unicode.

#include <iostream>
#include <string>

int main() {
    // 使用std::string
    std::string str = "Hello, C++11!";

    // 使用std::u32string和std::u16string
    std::u32string u32str = U"Hello, Unicode!";
    std::u16string u16str = u"Hello, Unicode!";

    std::cout << str << std::endl;
    std::wcout << u32str << std::endl;
    std::wcout << u16str << std::endl;

    return 0;
}

C++17

En C++17 se introdujo el archivo de cabecera , que ofrece una alternativa ligera y de solo lectura a los tipos de cadena del archivo de cabecera . Estas vistas de cadena son análogas a las cadenas descritas anteriormente. Por ejemplo, el equivalente en de std::u32string es std::u32string_view (es decir, std::basic_string_view).

Esto resulta especialmente útil en funciones que necesitan leer una cadena pero no modificarla. En lugar de crear una copia de la cadena para la función, ¡podemos simplemente observar la cadena existente! Además, es muy flexible: no solo permite convertir cadenas de estilo C++ en vistas de cadena, sino incluso cadenas de estilo C. A continuación, un ejemplo que demuestra el uso sencillo de std::string_view:

#include <iostream>
#include <string>
#include <string_view>

void printString(std::string_view str) {
  std::cout << str << std::endl;
}

int main() {
  std::string_view strv{"strv"}; // C++ string_view
  printString(strv);

  std::string str{"str"}; // C++ string
  printString(str);

  char cstr[] = "cstr"; // C-style string
  printString(cstr);

  return 0;
}

Salida:

strv
str
cstr

En este ejemplo, la función printString toma un std::string_view como parámetro, lo que la hace muy ligera y flexible: como no se crea ninguna copia de las cadenas, la función puede usarse de muchas maneras pasando cadenas de estilo C y de estilo C++.

C++20

En C++20 se introdujeron varias funciones miembro nuevas y útiles, entre ellas starts_with(…) y ends_with(…). Como sugieren sus nombres, estas funciones determinan si una cadena (o vista de cadena) empieza o termina con un determinado carácter o con un determinado std::string_view. He aquí un ejemplo sencillo:

#include <cassert>
#include <string>
#include <string_view>

int main() {
  const std::string str{"Hello World!"};

  assert(str.starts_with('H'));
  assert(str.ends_with('!'));

  assert(str.starts_with("Hello")); // 隐式转换为std::string_view
  assert(str.ends_with("World!")); // 隐式转换为std::string_view

  return 0;
}

C++23

En C++23 se introdujo contains, que permite comprobar si una cadena contiene una subcadena especificada.

// 这是一个假设的C++23示例,实际上并不可用
#include <iostream>
#include <string>

int main() {
    std::string str = "C++23 introduces contains function.";

    if (str.contains("introduces")) {
        std::cout << "The string contains 'introduces'." << std::endl;
    } else {
        std::cout << "The string does not contain 'introduces'." << std::endl;
    }

    return 0;
}

https://en.cppreference.com/w/cpp/string/basic_string/contains

Conclusión

Al trabajar con cadenas en código C++ moderno, conviene procurar que el código sea lo más flexible y eficiente en memoria posible. Usar puede ayudar enormemente en ello. Además, considera usar las funciones miembro de cadena más recientes, como starts_with y ends_with, para obtener código de análisis de cadenas legible y fácil de implementar. Y C++23 simplifica el cálculo con contains: cada vez más moderno.

Temas relacionados

Comentarios