El std::string tiene algunas desventajas, una de las situaciones más comunes son las strings constantes. A continuación se muestra el programa que demuestra el problema que se produce al tratar strings constantes con std::string:
Programa 1:
C++
// C++ program to demonstrate the // problem occurred in string #include <iostream> #include <string> using namespace std; // Driver Code int main() { char str_1[]{ "Hello !!, GeeksforGeeks" }; string str_2{ str_1 }; string str_3{ str_2 }; // Print the string cout << str_1 << '\n' << str_2 << '\n' << str_3 << '\n'; return 0; }
Producción:
Explicación: El resultado es el mismo que se esperaba. Pero, para ver «Hello !!, GeeksforGeeks» dos veces , std::string realiza sobrecargas en la memoria dos veces. Pero aquí la tarea era leer la string («¡¡Hola!!, GeeksforGeeks») , y no se requiere ninguna operación de escritura en ella. Entonces, solo para mostrar una string, ¿por qué asignar memoria varias veces? Para manejar las strings de forma más eficiente, C++17 propuso std::string_view() que proporciona la vista de char str[] predefinido sin crear un nuevo objeto en la memoria.
Inconveniente de std::string : En el ejemplo anterior, la misma string str_1 se imprime dos veces asignando dos variables de string diferentes. Entonces, para las variables str_2 y str_3 , la memoria se asignó usando la asignación de memoria estática , y eso causa una sobrecarga en nuestra memoria dos veces.
Beneficios de std::string_view :
- Ligero y más barato: std::string_view es muy ligero, más barato y se utiliza principalmente para proporcionar la vista de la string. Cada vez que se crea string_view , no hay necesidad de copiar la string de la manera que se hizo en el ejemplo anterior que era ineficiente y estaba causando una sobrecarga en la memoria. Hace que el proceso de copia de la string sea bastante eficiente y nunca crea ninguna copia de la string cuando la modificación se realiza en la string vista, los cambios realizados han aparecido en std::string_view .
- Mejor rendimiento: std::string_view es mejor que const std::string& porque elimina la restricción de tener un objeto std::string al principio de la string, ya que std::string_view se compone de dos elementos, el primero es const char* que apunta a la posición inicial de la array y el segundo es size .
- Admite funciones cruciales: std::string_view admite principalmente todas las funciones cruciales que se aplican sobre std::string como substr , compare, find, operadores de comparación sobrecargados (p. ej., ==, <, >, !=) . Entonces, en la mayoría de los casos, elimina la restricción de tener una declaración de objeto std::string cuando nuestra preferencia es de solo lectura.
std::string_view : la biblioteca C++17 ha propuesto un tipo estándar de string ( std::string_view ) que es diferente del std::string habitual.
- std::string_view proporciona un objeto liviano que ofrece acceso de solo lectura a una string o parte de una string usando una interfaz similar a la interfaz de std::_string y simplemente se refiere a la secuencia de caracteres contigua. A diferencia de std::string, que conserva su propia copia de la string, también proporciona una vista de una string que se define en otra parte del código fuente.
- se compone de dos miembros: un const char* que apunta al inicio de la array char y el _size. Es una referencia no propietaria a una string en sí misma.
- Se define en el encabezado (#include <string_view>) y la plantilla de clase std::string_view es la siguiente:
template<class CharT, class Traits = std::char_traits<CharT>> class basic_string_view;
La plantilla de clase string_view explica acerca de un objeto que puede hacer referencia a una secuencia contigua constante de char o una array de objetos similares a char con el primer elemento de la secuencia en la posición cero.
A continuación se muestra la versión exacta del código fuente anterior usando std::string_view :
Programa 2:
C++
// C++ program to implement // the above approach #include <iostream> using namespace std; #include <string_view> // Driver code int main() { // View the text "hello", which is // stored in the binary string_view str_1{ "Hello !!, GeeksforGeeks" }; // View of the same "hello" string_view str_2{ str_1 }; // View of the same "hello" string_view str_3{ str_2 }; std::cout << str_1 << '\n' << str_2 << '\n' << str_3 << '\n'; return 0; }
Producción-
Explicación: La salida sería la misma que la anterior, pero no se crean más copias de la string “¡¡Hola!!, GeeksforGeeks” en la memoria.
Parámetros en std::string_view :
Tipo de caracteres:
el tipo de caracteres define el tipo de caracteres que se almacenan en string_view. La biblioteca estándar de C++ proporciona las siguientes definiciones de tipo para las especializaciones de la plantilla descrita anteriormente.
- string_view para elementos de tipo char
- wstring_view , para wchar_t
- u16string_view para char16_t
- u32string_view para char32_t
A continuación se muestra el programa C++ para ilustrar el tipo Char:
Programa 3:
C++
// C++ program for the above approach #include <iostream> #include <string> #include <string_view> using namespace std; string_view sur_name(wstring_view x) { return x.substr(6); } // Driver Code int main() { // Basic_string_view<wchar_t> wstr // (L"Madhav_Mohan"); both are equivalent const wchar_t* str1{ L"Madhav_Mohan" }; cout << your_name(str1); return 0; }
Producción-
Ejemplo de std::string_view: Los siguientes ejemplos muestran que la mayoría de las funciones basadas en strings se pueden usar con std::string_view como se usa str.compare() , str.back() , str.cend() y str. en() funciones.
Programa 4:
C++
// C++ program to implement // the above approach #include <iostream> #include <string_view> using namespace std; string to_alpha(int r) { if (r < 0) return " less than "; else if (r == 0) return " equal to "; else return " greater than "; } // Driver code int main() { char str{ "Muddy" }; char str_1{ "Maddy" }; string_view str_2{ str_1 }; // This line prints Maddy cout << str_2 << '\n'; // Change 'M' to 'D' in arr str_1[0] = 'D'; // This line prints Daddy cout << str_2 << '\n'; cout << str_2.at(2); cout << str_2.back(); cout << " is last char of str_2 is y " << (str_2.back() == 's'); cout << " is last char of str_2 is y " << boolalpha << (str_2.back() == 's'); // In above statement boolalpha is // used to give the boolean result // in True or False int cmp{ str_1.compare(str_2) }; cout << to_alpha(cmp }; int cmp_1 = str.compare(1, 4, str_2); cout << "last three characters of str are" << to_alpha(cmp_1) << "str_2.\n"; return 0; }
Producción:
Modificación de std::string_view : en C++20 se han agregado algunas funciones nuevas como str.remove_suffix(), str.remove_suffix() usando estas funciones puede modificar std::string_view. Me gusta puede eliminar el sufijo selectivo o los prefijos de la string dada.
Programa 5:
C++
// C++ program to implement // the above approach #include <iostream> #include <iterator> #include <string_view> using namespace std; // Driver code int main() { string_view str_1{ "Maddy" }; cout << str_1 << '\n'; string_view str_2{ "Daddy" }; cout << str_2 << '\n'; string_view var{ "Hello !!, GeeksforGeeks" }; cout << var << '\n'; cout << var.starts_with("Hi !!") << '\n'; cout << var.ends_with("GeeksforGeeks !!") << '\n'; // Remove the first characters. str_1.remove_prefix(1); cout << str_1 << '\n'; // Remove the last 2 characters. str_1.remove_suffix(2); std::cout << str_1 << '\n'; return 0; }
Producción:
A continuación se muestra el ejemplo de algunas otras operaciones que se pueden realizar con std::string_view:
Programa 6:
C++
// C++ program to implement the // above approach #include <array> #include <cstddef> #include <iostream> #include <stdexcept> #include <string> #include <string_view> using namespace std; // Driver code int main() { constexpr string_view str{ "Daddy" }; constexpr string_view str1{ "Maddy" }; string str2{}; // Copy data of str1 into str2 str1.copy(str2.data(), 4); // This line prints Madddy cout << str2.data() << '\n'; if ((str.compare(str2)) != 0) cout << str << " " << "doesn't = to" << " " << str1 << '\n'; cout << str1.starts_with("Mad"); cout << '\n' << str.starts_with("Pad") << '\n'; cout << str1.ends_with("ddt"); cout << '\n' << str.ends_with("ddy") << '\n'; // Checks whether the given string contains // the given substring or character constexpr string_view s1{ "Hello! Madhav" }; // Position of the first character that // match first constexpr string_view str3{ "Hi! Maddy" }; size_t found = str3.find(str1); cout << found << '\n'; // Find the last occurrence of a substring cout << '\n' << str3.rfind('d'); // Gives the first time occurred char's position cout << '\n' << str3.find_first_of("d"); // Gives the last time occurred char's position cout << '\n' << str3.find_last_of("d"); // Finds the first char that's not equal to // any of the char(s) in the given string cout << '\n' << str3.find_last_not_of(str, 6); // It givesIndex of first unmatched character // when successful or string::npos if no such // character found. It searches for the first // char that doesn't match any of the char(s) // that has given in the argument cout << '\n' << str3.find_last_not_of(str, 4); return 0; }
Producción:
Strings terminadas no nulas : a diferencia de las strings C y std::string, que necesitan un terminador de string (‘\ 0’) al final de una string, std::string_view no necesita terminadores nulos para marcar el final de la string. Porque mantiene un registro de la longitud de la string.
A continuación se muestra el programa C++ para implementar el enfoque anterior:
Programa 7:
C++
// C++ program to implement // the above approach #include <iostream> // For std::size #include <iterator> #include <string_view> using namespace std; // Driver code int main() { // No null-terminator. char name[]{ 'M', 'a', 'd', 'h', 'a', 'v' }; // Here name isn't null-terminated. // We need to pass the length manually. // Because name is an array, we can // use std::size to get its length. string_view str_1{ \name, size(name) }; // This is safe and cout knows how to // print std::string_views. cout << str_1 << '\n'; return 0; }
Producción:
Conversión de std::string_view en std::string : se deben usar métodos de conversión explícitos porque la conversión implícita no ayudará aquí.
A continuación se muestra el programa C++ para implementar la conversión de std::string_view a std::string:
Programa 8:
C++
// C++ program to implement // the above approach #include <iostream> #include <string> #include <string_view> using namespace std; void print(string s) { cout << s << '\n'; } // Driver code int main() { string_view str_1{ "Madhav" }; str_1.remove_suffix(3); // compile error: won't implicitly // convert // print(str_1); // explicit conversion string str_2{ str_1 }; print(str_2); // It'll work print(static_cast<string>(str_1)); return 0; }
Producción:
Conversión de std::string_view a string de estilo C: funciones como strlen(), estas funciones necesitan una string de estilo C para ser utilizadas. Por lo tanto, siempre que sea necesario convertir un std::string_view en una string de estilo C, puede hacerlo convirtiéndolo primero en un std::string.
A continuación se muestra el programa C++ para implementar el enfoque anterior:
Programa 9:
C++
// C++ program to implement // the above approach #include <cstring> #include <iostream> #include <string> #include <string_view> // Driver code int main() { string_view str_1{ "Madhav" }; str_1.remove_suffix(3); // Create a std::string from // the std::string_view string str_2{ str_1 }; // A Null_terminated C-style string. auto Null_Terminated{ str_2.c_str() }; // Pass the null-terminated string // to the function that we want to use. cout << str_2 << " has " << strlen(Null_Terminated) << " letter's\n"; return 0; }
Producción:
Problemas de alcance con std::string_view: std::string_view proporciona una vista, por lo que permanece independiente de una string de la que proporciona una vista, y proyecta la vista de la string a menos que la string vista esté dentro del alcance, pero en caso de que el alcance de las strings vistas se apaga, luego std::string_view no tiene nada que proyectar, por lo que muestra un comportamiento indefinido. std::string_view siempre necesita un literal de string o una string que ha sido creada por un std::string dentro del alcance para proyectar la vista de la string, pero tan pronto como el alcance muere, std::string_view no puede crear ninguna string por sí mismo porque es solo una vista.
A continuación se muestra el ejemplo para implementar el enfoque anterior:
Programa 10:
C++
// C++ program to implement // the above approach #include <iostream> #include <string> #include <string_view> using namespace std; string_view ask_name() { cout << "Write your surname?\n"; // A std::string is needed, because // std::cin needs to modify it. string str_1{}; cin >> str_1; // Pass str_1 to std::string_view string_view str_2{ str_1 }; cout << str_2 << '\n'; // str_1 dies, and so does the // string that str created. return str_2; } // Driver code int main() { std::string_view str_2{ ask_name() }; // str_2 is observing a string that // already died. // Undefined behavior you'll observe cout << your surname is << str_2 << '\n'; return 0; }
Producción:
Ejecución de std::string_view con la función data(): La función data() escribe los caracteres de la string en una array. Devuelve un puntero a la array, obtenido de la conversión de string a la array. Su tipo de retorno no es una string C válida ya que no se agrega ningún carácter ‘\0’ al final de la array.
A continuación se muestra el programa C++ para implementar el enfoque anterior:
Programa 11:
C++
// C++ program to implement // the above approach #include <cstring> #include <iostream> #include <string> using namespace std; #include <string_view> // Driver code int main() { string str{ "Madhav_Mohan" }; string_view str1{ str.data() }; cout << str1 << endl; string_view str2{ str1.substr(6) }; string_view str3{ str2 }; cout << str3; return 0; }
Producción:
Funciones de no miembros:
operator== operator!= (has been removed in C++20) operator< (has been removed in C++20) operator> (has been removed in C++20) operator<= (has been removed in C++20) operator>= (has been removed in C++20) operator<=> (has newly been included C++20)
Nota : Std::string_view solo se ejecuta en C++ 17 o en versiones anteriores. Hay una serie de funciones que se incorporan con std::string_view, algunas de ellas son nuevas (C++ 20) y otras son antiguas. A continuación, me refiero a la dirección web donde puede obtenerlos también en profundidad.
Publicación traducida automáticamente
Artículo escrito por madhav_mohan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA