22.2 – Создание и уничтожение std::string

Добавлено 1 октября 2021 в 17:39

В этом уроке мы рассмотрим, как создавать объекты std::string, а также как создавать строки из чисел и наоборот.

Создание строки

Строковые классы имеют ряд конструкторов, которые можно использовать для создания строк. Здесь мы рассмотрим каждого из них.

Примечание: string::size_type преобразуется в size_t, который является тем же целочисленным типом без знака, который возвращается оператором sizeof. Его фактический размер зависит от среды. Для целей этого руководства представьте его как unsigned int.

string::string()

Конструктор по умолчанию. Создает пустую строку.

Пример кода:

std::string sSource;
std::cout << sSource;

Вывод:

 

string::string(const string& strString)

Конструктор копирования. Этот конструктор создает новую строку как копию strString.

Пример кода:

std::string sSource{ "my string" };
std::string sOutput{ sSource };
std::cout << sOutput;

Вывод:

my string

string::string(const string& strString, size_type unIndex)
string::string(const string& strString, size_type unIndex, size_type unLength)

Этот конструктор создает новую строку, содержащую не более unLength символов из strString, начиная с индекса unIndex.

  • Если встречается NULL, копирование строки завершится, даже если значение unLength не было достигнуто.
  • Если значение unLength не указано, будут использоваться все символы, начиная с unIndex.
  • Если значение unIndex больше размера строки, будет выброшено исключение out_of_range.

Пример кода:

std::string sSource{ "my string" };
std::string sOutput{ sSource, 3 };
std::cout << sOutput<< '\n';
std::string sOutput2(sSource, 3, 4);
std::cout << sOutput2 << '\n';

Вывод:

string
stri

string::string(const char *szCString)

Этот конструктор создает новую строку из строки szCString в стиле C, но не включая завершающий ноль.

  • Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение length_error.
  • Предупреждение: szCString не должна быть равна nullptr.

Пример кода:

const char *szSource{ "my string" };
std::string sOutput{ szSource };
std::cout << sOutput << '\n';

Вывод:

my string

string::string(const char *szCString, size_type unLength)

Этот конструктор создает новую строку из первых unLength символов из строки szCString в стиле C.

  • Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение length_error.
  • Предупреждение: только для этой функции нули в szCString не обрабатываются как символы конца строки! Это означает, что можно выйти за конец строки, если значение unLength слишком велико. Будьте осторожны, чтобы не переполнить строковый буфер!

Пример кода:

const char *szSource{ "my string" };
std::string sOutput(szSource, 4);
std::cout << sOutput << '\n';

Вывод:

my s

string::string(size_type nNum, char chChar)

Этот конструктор создает новую строку, инициализированную nNum вхождениями символа chChar.

  • Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение length_error.

Пример кода:

std::string sOutput(4, 'Q');
cout << sOutput << endl;

Вывод:

QQQQ

template string::string(InputIterator itBeg, InputIterator itEnd)

Этот конструктор создает новую строку, инициализированную символами диапазона [itBeg, itEnd).

  • Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение length_error.

Здесь нет примера, поскольку это достаточно запутанный способ создания строки, и вы вряд ли когда-то им не воспользуетесь.

Уничтожение строки

string::~string()

Деструктор. Он уничтожает строку и освобождает память.

Здесь также нет примера кода, поскольку деструктор не вызывается явно.

Создание строк из чисел

Одним из заметных упущений в классе std::string является отсутствие возможности создавать строки из чисел. Например:

std::string sFour{ 4 };

выдает следующую ошибку:

c:vcprojectstest2test2test.cpp(10) : error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it)' : cannot convert parameter 1 from 'int' to 'std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it'

Помните, что я сказал о строковых классах, вызывающих страшно выглядящие сообщения об ошибках? Важная информация в сообщении находится здесь:

cannot convert parameter 1 from 'int' to 'std::basic_string

Другими словами, компилятор пытался преобразовать ваш int в строку, но потерпел неудачу.

Самый простой способ преобразовать числа в строки – задействовать класс std::ostringstream. std::ostringstream уже настроен для приема входных данных из различных источников, включая символы, числа, строки и т.д. Он также может выводить строки (либо с помощью оператора извлечения >>, либо с помощью функции str()) . Дополнительные сведения об std::ostringstream смотрите в разделе «23.4 – Классы потоков для строк».

Вот простое решение для создания std::string из различных типов входных данных:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
inline std::string toString(T tX)
{
    std::ostringstream oStream;
    oStream << tX;
    return oStream.str();
}

Вот пример кода для его проверки:

int main()
{
    std::string sFour{ toString(4) };
    std::string sSixPointSeven{ toString(6.7) };
    std::string sA{ toString('A') };
    std::cout << sFour << '\n';
    std::cout << sSixPointSeven << '\n';
    std::cout << sA << '\n';
}

И вывод:

4
6.7
A

Обратите внимание, что в этом решении не выполняется проверка на ошибки. Возможно, что вставка tX в oStream не удастся. Подходящим решением в случае сбоя преобразования было бы генерирование исключения.

Преобразование строк в числа

Аналогично решению, приведенному выше:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
inline bool fromString(const std::string& sString, T &tX)
{
    std::istringstream iStream(sString);
    // извлекаем значение в tX, возвращаем true в случае успеха
    return !(iStream >> tX).fail(); 
}

Вот пример кода для его проверки:

int main()
{
    double dX;
    if (fromString("3.4", dX))
        cout << dX << '\n';
    if (fromString("ABC", dX))
        cout << dX << '\n';
}

И вывод:

3.4

Обратите внимание, что второе преобразование завершилось неудачей и вернуло false.

Теги

C++ / CppLearnCppstd::istringstreamstd::ostringstreamstd::stringSTL / Standard Template Library / Стандартная библиотека шаблоновДля начинающихКонструктор / Constructor / ctor (программирование)ОбучениеПрограммированиеСтрокаШаблон / Template

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.