|
Программирование >> Разработка устойчивых систем
string bigNewsCI saw Elvis in a UFO. ): cout bigNews endl: Сколько данных фактически получено? cout Size = bigNews.size() endl: Сколько данных можно сохранить без перераспределения памяти? cout Capacity = bigNews.capacityO endl: Вставка строки в bigNews в позицию перед bigNews[l] bigNews.insert(1. thought Г): cout bigNews endl: cout Size = bigNews.SizeO endl: cout Capacity = bigNews.capacityО endl: Резервирование достаточного объема памяти bigNews.reserve(500): Присоединение в конец строки bigNews.append( Ive been working too hard. ): cout bigNews endl: cout Size = bigNews.SizeO endl: cout Capacity = bigNews.capacityО endl: } III:- В одном из компиляторов был получен следующий результат: I saw Elvis in а UFO. Size = 22 Capacity = 31 I thought I saw Elvis in a UFO. Size = 32 Capacity = 47 I thought I saw Elvis in a UFO. Ive been working too hard. Size = 59 Capacity = 511 Из приведенного примера видно, что хотя вы снимаете с себя большую часть ответственности за выделение памяти и управление ею в строках, класс string предоставляет в ваше распоряжение ряд средств для контроля за их размером. Обратите внимание, как легко был изменен размер блока памяти, выделенного под хранение символов строки. Функция size() возвращает текущее количество символов, она идентична функции length(). Функция capacity() возвращает размер текущего блока памяти, выделенного для хранения данных строки (то есть количество символов, которые можно сохранить в строке без необходимости выделения дополнительной памяти). Функция reserve() является средством оптимизации, выражающим ваше намерение зарезервировать определенный объем памяти для будущего использования; capacity() всегда возвращает значение, по крайней мере не меньшее того, которое было задано при последнем вызове reserve(). Функция resize() дополняет строку пробелами, если новый размер больше текущего, или усекает ее в противном случае (перегруженная версия resize() позволяет задать символ для дополнения строки). Точный алгоритм выделения памяти функциями класса string зависит от реализации библиотеки. При тестировании предыдущего примера в одной из реализаций оказалось, что память выделялась с выравниванием по границе машинных слов, при этом один байт резервировался. Проектировщики класса string стремились к тому, чтобы строковые объекты С++ по возможности использовались вместе с символьными массивами С. Скорее всего, именно этот факт отразился в дан- ных о емкости строк, выводимых в примере StrSize.cpp: резервирование одного байта позволяет легко вставить нуль-терминатор. Замена символов в строках Функция вставки символов insert() чрезвычайно удобна: вам не придется беспокоиться о том, чтобы вставляемые символы не вышли за пределы текущего блока памяти и не стерли символы, следующие за точкой вставки. Строка расширяется, и существующие символы вежливо подвигаются, уступая место новым. Впрочем, иногда такое поведение оказывается нежелательным. Если вы хотите, чтобы существующие символы были заменены новыми, воспользуйтесь функцией перезаписи гер1асе(). Существует несколько перегруженных версий гер1асе(), но простейшая форма получает три аргумента: начальную позицию в строке; количество символов, заменяемых в исходной строке; и строку замены (длина которой может не совпадать со вторым аргументом). Пример: : C03:Str1ngReplace.cpp Простейший поиск с заменой в строках. #1 nclude <cassert> #1 nclude <str1ng> using namespace std; int mainO { string sCA piece of text ); string tag( $tag$ ): s.insert(8. tag + ): assert(s == A piece $tag$ of text ); int start = s.find(tag): assert (start ==8); assert(tag.SizeO ~ 5); s.replace(start. tag.sizeO. hello there ); assert(s == A piece hello there of text ); } III:- Строка tag сначала вставляется в s (обратите внимание: вставка производится перед заданной позицией, и после tag еще вставляется дополнительный пробел). Далее выполняются операции поиска и замены. Прежде чем вызывать гер1асе(), стоит проверить, удалось ли найти искомую подстроку. В предыдущем примере для замены использовался тип char*, но существует перегруженная версия гер1асе() с аргументом типа string. Далее приводится более полный пример с заменой подстроки: ; СОЗ;Replace.Срр #1 nclude <cassert> #1nclude <cstddef> Для size t #include <str1ng> using namespace std; void replaceChars(str1ng& modifyMe. const strings findMe. const strings newChars) { Найти в modifyMe подстроку findMe начиная с позиции 0. size t 1 = modifyMe.find(findMe, 0); Найдена ли заменяемая подстрока? if (i ! = string; :npos) Заменить найденную подстроку содержимым newChars int mainO { string bigNews = I thought I saw Elvis in a UFO. I have been working too hard. ; string replacement( wig ): string findMe( UFO ): Найти и заменить в bigNews подстроку UFO : replaceChars(bigNews. findMe, replacement): assert(bigNews == I thought I saw Elvis in a wig. I have been working too hard. ): } III:- Если функция replace не находит искомую подстроку, она возвращает string::npos - статическую константу класса string, которая представляет несуществующую позицию символа. В отличие от insert(), функция гер1асе() не расширяет область данных строки при копировании в середину существующей последовательности символов. Тем не менее, она расширит область данных при необходимости, например, если в результате замены исходная строка выходит за пределы текущего блока. Пример: : C03:ReplaceAndGrow.cpp #include <cassert> linclude <string> using namespace std: int mainO { string bigNews( I have been working the grave. ): string replacement( yard shift. ): Первый аргумент означает: заменить символы за концом существующей строки : bigNews.replace(bigNews.SizeO - 1. replacement.size(). replacement): assert(bigNews == I have been working the graveyard shift. ): } III:- Вызов replace() начинает замену за концом существующего массива, что эквивалентно операции присоединения символов. В этом случае функция гер1асе() соответствующим образом расширяет массив. Возможно, вы наскоро просматриваете эту главу в поисках рецепта для выполнения относительно простой операции, такой как замена всех вхождений одного символа другим символом. Замена вроде бы относится к делу, но возня с поиском, фуппами символов, позициями и т. д. выглядят слишком сложно. Не позволяет ли класс string просто заменить один символ другим во всей строке? Такую функцию легко написать на базе функций find() и гер1асе(): : СОЗ:ReplaceAll.h lifndef REPLACEALL H Idefine REPLACEALL H #include <string> std::strings replaceAll(stringS context. Наибольшее значение, которое по умолчанию может быть представлено для типа sizetype строкового распределителя памяти (std::size t по умолчанию). modifyMe.replaced. findMe.sizeO, newChars);
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |