22.4 – Доступ к символам std::string и преобразование в массивы в стиле C
Доступ к символам
Есть два почти идентичных способа доступа к символам в строке. Более простой и быстрой версией является перегруженный operator[]
:
char& string::operator[] (size_type nIndex)
const char& string::operator[] (size_type nIndex) const
const char& string::operator[] (size_type nIndex) const
Обе эти функции возвращают символ с индексом nIndex
.
- Передача недопустимого индекса приводит к неопределенному поведению.
- Использование
length()
в качестве индекса допустимо только для константных строк и возвращает значение, сгенерированное конструктором строки по умолчанию. Делать это не рекомендуется. - Поскольку возвращаемым типом является
char&
, вы можете использовать его для редактирования символов в строке.
Пример кода:
std::string sSource{ "abcdefg" };
std::cout << sSource[5] << '\n';
sSource[5] = 'X';
std::cout << sSource << '\n';
Вывод:
f
abcdeXg
Также есть еще и неоператорная версия. Эта версия работает медленнее, поскольку использует исключения для проверки допустимости nIndex
. Если вы не уверены, допустимо ли значение nIndex
, то для доступа к символам строки вы должны использовать эту версию:
char& string::at(size_type nIndex)
const char& string::at(size_type nIndex) const
const char& string::at(size_type nIndex) const
Обе эти функции возвращают символ с индексом nIndex
.
- Передача недопустимого индекса приводит к исключению
out_of_range
. - Поскольку возвращаемым типом является
char&
, вы можете использовать его для редактирования символов в строке.
Пример кода:
std::string sSource{ "abcdefg" };
std::cout << sSource.at(5) << '\n';
sSource.at(5) = 'X';
std::cout << sSource << '\n';
Вывод:
f
abcdeXg
Преобразование в массивы в стиле C
Многие функции (включая все функции C) ожидают, что строки будут в формате строк в стиле C, а не в виде std::string
. По этой причине std::string
предоставляет 3 различных способа преобразования объектов std::string
в строки в стиле C.
const char* string::c_str() const
Возвращает содержимое строки как константную строку в стиле C.
- Добавляется завершающий ноль.
- Строка в стиле C принадлежит объекту
std::string
и не должна удаляться.
Пример кода:
std::string sSource{ "abcdefg" };
std::cout << std::strlen(sSource.c_str());
Вывод:
7
const char* string::data() const
Возвращает содержимое строки как константную строку в стиле C.
- Добавляется завершающий ноль. Эта функция выполняет то же действие, что и
c_str()
. - Строка в стиле C принадлежит объекту
std::string
и не должна удаляться.
Пример кода:
std::string sSource{ "abcdefg" };
const char *szString{ "abcdefg" };
// memcmp сравнивает первые n символов двух строк в стиле C и возвращает 0, если они равны
if (std::memcmp(sSource.data(), szString, sSource.length()) == 0)
std::cout << "The strings are equal";
else
std::cout << "The strings are not equal";
Вывод:
The strings are equa
size_type string::copy(char *szBuf, size_type nLength) const
size_type string::copy(char *szBuf, size_type nLength, size_type nIndex) const
size_type string::copy(char *szBuf, size_type nLength, size_type nIndex) const
Оба варианта копируют не более nLength
символов строки в szBuf
, начиная с символа nIndex
.
- Возвращается количество скопированных символов.
- Завершающий ноль не добавляется. Вызывающий должен обеспечить инициализацию
szBuf
значениемNULL
или завершить строку, используя возвращенную длину. - Вызывающий отвечает за непереполнение
szBuf
.
Пример кода:
std::string sSource{ "sphinx of black quartz, judge my vow" };
char szBuf[20];
int nLength{ static_cast<int>(sSource.copy(szBuf, 5, 10)) };
szBuf[nLength] = '\0'; // завершаем строку в буфере нулем
std::cout << szBuf << '\n';
Вывод:
black
Если вам не нужна максимальная эффективность, c_str()
– самая простая и безопасная для использования функция из трех показанных выше.