Ответ
В C++ существует два основных способа работы со строками, которые отражают эволюцию языка.
1. Строки в стиле C (C-strings)
Это массивы символов (char или wchar_t), завершающиеся нуль-терминатором (' ').
const char* cstr = "Hello"; // "Hello " хранится в статической памяти
char cstr_array[] = {"World"}; // Массив на стеке: 'W','o','r','l','d',' '
char stack_str[10]; // Буфер, который нужно заполнять аккуратно
strcpy(stack_str, "Hi"); // Опасность: strcpy не проверяет границы буфера.
// Безопаснее (C11/C++): strncpy(stack_str, "Hi", sizeof(stack_str));
Недостатки: Управление памятью вручную, риск переполнения буфера, сложность операций (требуют функций из <cstring>).
2. Класс std::string (и std::wstring)
Это специализация шаблона std::basic_string для типа char. Он инкапсулирует динамический массив символов.
#include <string>
#include <iostream>
std::string s1; // Пустая строка
std::string s2 = "Initial"; // Инициализация из C-строки
std::string s3(10, 'x'); // "xxxxxxxxxx"
std::string s4(s2, 0, 3); // "Ini" (подстрока)
// Основные операции
s2.append(" Value"); // "Initial Value"
s2 += "!"; // Конкатенация
size_t pos = s2.find("Val"); // pos = 8
std::string sub = s2.substr(pos, 5); // "Value"
s2.replace(pos, 5, "Data"); // "Initial Data!"
// Доступ к данным
char ch = s2[0]; // 'I' (без проверки границ)
char ch_safe = s2.at(0); // 'I' (с проверкой, throws std::out_of_range)
const char* c_ptr = s2.c_str(); // Для передачи в C-API
const char* data_ptr = s2.data(); // Доступ к внутреннему массиву (C++17)
Внутреннее устройство (SSO - Small String Optimization):
Во многих реализациях std::string использует оптимизацию для коротких строк. Небольшие строки (до ~15-23 символов, зависит от реализации) хранятся внутри самого объекта на стеке, избегая динамического выделения памяти. Длинные строки хранят указатель на память в куче.
std::string short_str = "SSO!"; // Вероятно, хранится в буфере внутри объекта
std::string long_str = "This is a very long string that will require heap allocation";
Ключевые преимущества std::string:
- Автоматическое управление памятью: Само расширяется при конкатенации.
- Безопасность: Методы проверяют границы (например,
at()). - Богатый интерфейс: Поиск, замена, вставка, сравнение.
- Совместимость с STL: Работает с алгоритмами (
std::sort,std::find) и итераторами. - Поддержка