Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STL5 / lab2-string / lab2-string.doc
Скачиваний:
9
Добавлен:
10.04.2015
Размер:
177.66 Кб
Скачать

Подстроки

Ранее были описаны способы поиска нужной подстроки или символа в строке, результатом работы функция поиска является индекс искомой подстроки. Если же необходимо создать отдельный объект строку, для этого можно использовать функция substr:

template <class Ch, class Tr = char_traits<Ch>, class A = allocator<Ch> >

class std::basic_string

{

public:

basic_string substr(size_type i = 0, size_type n = npos);

};

substrсоздает объект классаstringиз подстроки, начиная с индексаiи состоящей изnсимволов.nposв данном случае, означает максимально возможную подстроку, так например вызовstr.substr(2,npos) создаст строку, которая будет проинициализирована символами строкиstrначиная с индекса 2 и до конца, т.е. подстрока будет содержать строкуstrбез первых двух символов.

Следующий фрагмент показывает как можно получить строку содержащую первое слово в строке:

string str(“ Word1, word2 “);

string letter(“abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY”);

int ind1,ind2;

ind1 = str.find_first_of(letter);

ind2 = str.find_first_of(letter,ind1+1);

string first_word = str.substr(ind1,ind2-ind1);

// first_word содержит “Word”

Взаимодействие stringи с-строк

Как отмечалось ранее класс stringстандартной библиотеки является таким же современным заменителем С-строк, как и класс вектор является заменителем встроенных массивов. Как и в случае с классомvectorважным остается возможность интеграции нового С++ кода, использующегоstring, со старым кодом, использующим С строки в видеconstchar*.

Преобразование С-строки в stringдостаточно просто, для этого можно использовать описанные выше конструктор копирования и оператор присваивания, которые принимаю в качестве аргументаconstchar*.

Для преобразования stringвconstchar* или массив символом можно использовать следующие методы:

template <class Ch, class Tr = char_traits<Ch>, class allocator = allocator<Ch> >

class basic_string

{

public:

// преобразование в С строку

const Ch* c_str() const;

const Ch* data() const;

size_type copy(Ch* p, size_type n, size_type pos = 0) const;

};

Метод data()записывает символы строки в массив и возвращает указатель на него, этот массив не содержит завершающего нулевого символа. Массив принадлежит классуstringи пользователь не должен пытаться уничтожить его или пытаться перезаписать.

Метод c_str() аналогичен методуdata() за исключение того, что возвращаемый массив дополняется в конце нулевой символ. Другими словамиdata() создает массив символов, аc_str() С строку.

// функция конвертирующая строку в число

int convert(const string& str)

{

// воспользуемся стандартной функцией конвертирования С строк

return atio(str.c_str());

}

Массивы, указатели на которые возвращают data() иc_str(), могут быть использованы до тем пор пока строка от которой были получены эти массивы не была изменена, другими словами пока не была вызвана неконстантная функция член классаstring. После этого программист не может полагаться на содержимое этих массивов.

string str = “Simple string”;

const char* str_data = str.data();

// распечатаем массив поэлементно

int i;

for (i = 0; i < str.length(); i++)

{

printf(“%c”,str_data[i]);

}

// изменим строку

str[0] = ‘s’;

char first_ch = str_data[0]; // ошибка, строка изменена, массив полученный

//от data() может содержать не действительные

// данные, на него нельзя полагаться

Методы data() иc_str() позволяют получить доступ к символам хранящимся в строке в С-стиле, но только для чтения. Если есть необходимость каким-то образом обработать эти символы, то их необходимо скопировать в собственные буфер, для этой цели может быть использован методsize_type copy(Ch* p, size_type n, size_type pos = 0), который копирует не более чемnсимволов в буферp, начиная символа с индексомpos:

// Функция возвращает буфер доступный для чтения/записи и содержащий символы

// из переданной в качестве параметра строки

// полученный от функции буфер в последствии нужно будет освободить

// вызовом delete []

char* c_string(const string& str)

{

int length = str.length();

char* p = new char[length + 1]; // включая место для нулевого символа

str.copy(p,length);

return p;

}

Однако, если в программе части используются методы data(),c_str() иcopy(), стоит подумать не возможно ли сделать те же действия методами классаstring(или другими средствамиSTL) не прибегая к средствам обработке строк в стиле С.

1Более подробно о недостатка использования встроенных массивов см. лаб. работу посвященную классуvector

2Более детально свойства символов можно изучить в литературе поC++, например в книге Б. Страуструпа «Язык программирования С++», более детально изучить классы свойств в книге Д. Вандервуда и Н.М. Джосатиса «Шаблоны С++. Справочник разработчика»

3О распределителях памяти можно прочитать в книге Б. Страуструпа «Язык программирования С++» и книге С. Мейерса «Эффективное использованиеSTL»

4Стандартные алгоритмы рассматриваются в одной из следующих работ

5В действительности сравнение осуществляется с помощью функции traits::compare() определенной с классе свойств символов. Значение по умолчанию реализует описанное сравнение в лексикографическом смысле.

Соседние файлы в папке lab2-string