Resumen
El texto es el dato más frecuente de un programa: nombres, mensajes, líneas de un archivo, órdenes de un usuario. Esta clase lo trata como lo que es para C++, una secuencia de caracteres con operaciones propias. Presenta std::string, que se crea, se concatena, se compara y se recorre como un vector de char con oficio de texto; sus operaciones de búsqueda y extracción (find, substr, starts_with, contains) y el valor std::string::npos, con el que find dice que no encontró nada; std::string_view, la vista que observa un texto sin copiarlo, y la condición de la que depende: que el texto observado siga existiendo. Cierran la clase las cadenas de C, para leer código ajeno, y el orden en que C++ compara y ordena las palabras.
Objetivos de aprendizaje
- Usar las operaciones de
std::string(size,+,find,substr,starts_with,contains) para resolver problemas de texto. - Interpretar el resultado de
findy comprobarlo contrastd::string::npos, y predecir lo que ocurre si se lo trata como un número cualquiera. - Recibir texto en una función como
std::string_viewy explicar con un ejemplo por qué una vista no debe sobrevivir a la cadena que observa. - Leer código con cadenas de C y explicar sus diferencias con
std::string: el terminador nulo, el tamaño fijo y la suma de dos literales, que no compila.
La cadena std::string
Crear, concatenar, recorrer
La clase Caracteres, booleanos, conversiones y constantes presentó el carácter, char, como un número pequeño que una tabla convierte en letra. Un texto es una sucesión de caracteres; si esto es así, puede guardarse en un std::vector<char>, y lo que la clase Vectores enseñó de las secuencias valdría para él. Ahora bien, al texto se le piden operaciones que a una secuencia cualquiera no: pegarle otro texto, buscar en él una palabra, extraer un trozo, escribirlo de una vez. De ello se sigue un tipo propio, la cadena, std::string, de la cabecera <string>: un vector de char con oficio de texto.
#include <format>#include <print>#include <string>int main(){ const std::string first{"Ada"}; std::string greeting{"Hola, " + first}; greeting += '.'; std::println("{} ({} caracteres)", greeting, greeting.size()); std::println("Primero «{}», último «{}»", greeting[0], greeting.back()); int spaces{0}; for (const char c : greeting) { if (c == ' ') { ++spaces; } } std::println("Espacios: {}", spaces); const std::string code{std::format("{}-{:03}", "MAT", 7)}; std::println("{} {}", code, code == "MAT-007");}Hola, Ada. (10 caracteres)Primero «H», último «.»Espacios: 1MAT-007 trueLa línea 7 crea una cadena a partir de un literal. La 8 la concatena: el operador + entre una cadena y un literal produce una cadena nueva con los caracteres de ambos, uno a continuación del otro. La 9 añade un carácter al final con +=, que también admite una cadena o un literal. Lo demás es lo que ya se sabía de los vectores: size() cuenta los caracteres (10, porque la coma, el espacio y el punto también lo son), greeting[0] es el primero y back() el último, y el bucle de las líneas 13 a 17 recorre la cadena carácter a carácter con la forma de rango de la clase Bucles. Como el vector, una cadena admite además push_back, pop_back y empty, y la biblioteca de GCC 15, cuando no se optimiza, comprueba sus índices con operator[] (con optimización, esa comprobación desaparece).
Las dos últimas líneas cumplen lo que anunció la clase Diseñar con funciones. std::format, de <format>, recibe los mismos marcadores que std::println, con los mismos campos ({:03} rellena con ceros hasta tres cifras), pero en lugar de escribir el resultado lo devuelve como cadena: es la manera de construir un texto que después se guarda, se compara o se pasa a una función. Y == compara dos cadenas por su contenido: son iguales si tienen el mismo tamaño y los mismos caracteres en el mismo orden. Por tanto, code == "MAT-007" es true, aunque el texto de la izquierda se haya construido por partes y el de la derecha sea un literal.
Comparar
Además de == y !=, las cadenas admiten <, <=, > y >=, que las comparan en orden lexicográfico, el del diccionario: se recorren las dos a la par, y en la primera posición en que difieren decide el carácter menor; si una se agota antes sin diferencia alguna, la más corta es la menor. Así, "casa" < "cosa" porque 'a' < 'o' en la segunda posición, y "mar" < "marea" porque la primera es un prefijo de la segunda. Qué carácter es «menor» lo decide su código, no el alfabeto; la última sección de la clase muestra lo que de ello se sigue.
Cargando el contenido…