С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944), страница 47
Текст из файла (страница 47)
В следующем разделе мы коснемсяостальных вариантов.)Если слово заканчивается на "ses", как promises или purposes, нужно удалитьstring ses( "ses" );if ( ! word.compare( pos3, 3, ses )) {word.erase( pos3+l, 2 );return;суффикс "es"16:}Если слово кончается на "ous", как oblivious, fulvous, cretaceous, или на "is", какgenesis, mimesis, hepatitis, мы не будем изменять его. (Наша система несовершенна.Например, в слове kiwis надо убрать последнее 's'.) Пропустим и слова,оканчивающиеся на "ius" (genius) или на "ss" (hiss, lateness, less).
Нам поможетstring::size_type spos = 0;string::size_type pos3 = word.size()-3;// "ous", "ss", "is", "ius"string suffixes( "oussisius" );if ( !!!!word.compare(word.compare(word.compare(word.compare(pos3, 3, suffixes, spos, 3 )pos3, 3, suffixes, spos+6, 3pos3+l, 2, suffixes, spos+2,pos3+l, 2, suffixes, spos+4,||) ||2 ) ||2 ) )////////ousiusssisвторая форма функции compare():return;// удалим последнее 's'В противном случае удалим последнее 's':word.erase( pos3+2 );16 Конечно, в английском языке существуют исключения из правил. Наш эвристическийалгоритм превратит crises (множ. число от crisis – прим.
перев.) в cris. Ошибочка!С++ для начинающих281Имена собственные, например Pythagoras, Brahms, Burne-Jones, не подпадают подобщие правила. Этот случай мы оставим как упражнение для читателя, когда будемрассказывать об ассоциативных контейнерах.Но прежде чем перейти к ним, рассмотрим оставшиеся строковые операции.Упражнение 6.17Наша программа не умеет обрабатывать суффиксы ed (surprised), ly (surprisingly) иing (surprisingly).
Реализуйте одну из функций для этого случая:(a) suffix_ed()(b) suffix_ly()(c) suffix_ing()6.11. Дополнительные операции со строкамиВторая форма функции-члена erase() принимает в качестве параметров два итератора,ограничивающих удаляемую подстроку. Например, превратимstring name( "AnnaLiviaPlurabelle" );typedef string::size_type size_type;size_type startPos = name.find( 'L' )size_type endPos= name.find_1ast_of( 'b' );name.erase( name.begin()+startPos,в строку "Annabelle":name.begin()+endPos );Символ, на который указывает второй итератор, не входит в удаляемую подстроку.Для третьей формы параметром является только один итератор; эта форма удаляет всесимволы, начиная с указанной позиции до конца строки.
Например:name.erase( name. begin()+4 );оставляет строку "Anna".Функция-член insert() позволяет вставить в заданную позицию строки другую строкуили символ. Общая форма выглядит так:string_object.insert( position, new_string );position обозначает позицию, перед которой производится вставка. new_string можетstring string_object( "Missisippi" );string::size_type pos = string_object.find( "isi" );быть объектом класса string, C-строкой или символом:string_object.insert( pos+1, 's' );С++ для начинающихstring new_string ( "AnnaBelle Lee" );string_object += ' '; // добавим пробел// найдем начальную и конечную позицию в new_stringpos = new_string.find( 'B' );string::size_type posEnd = new_string.find( ' ' );string_object.insert(string_object.size(), // позиция вставкиnew_string, pos,// начало подстроки в new_stringposEnd// конец подстроки new_stringМожно выделить для вставки подстроку из new_string:)string_object получает значение "Mississippi Belle".
Если мы хотим вставить всесимволы new_string, начиная с pos, последний параметр нужно опустить.string sl( "Mississippi" );Пусть есть две строки:string s2( "Annabelle" );Как получить третью строку со значением "Miss Anna"?string s3;// скопируем первые 4 символа s1Можно использовать функции-члены assign() и append():s3.assign ( s1, 4 );// добавим пробелs3 теперь содержит значение "Miss".s3 += ' ';// добавим 4 первых символа s2Теперь s3 содержит "Miss ".s3.append(s2,4);s3 получила значение "Miss Anna". То же самое можно сделать короче:s3.assign(s1,4).append(' ').append(s2,4);282С++ для начинающихДругая форма функции-члена assign() имеет три параметра: второй обозначаетпозицию начала, а третий – длину.
Позиции нумеруются с 0. Вот как, скажем, извлечьstring beauty;// присвоим beauty значение "belle""belle" из "Annabelle":beauty.assign( s2, 4, 5 );// присвоим beauty значение "belle"Вместо этих параметров мы можем использовать пару итераторов:beauty.assign( s2, s2.begin()+4, s2.end() );В следующем примере две строки содержат названия текущего проекта и проекта,находящегося в отложенном состоянии. Они должны периодически обмениватьсяstring current_project( "C++ Primer, 3rd Edition" );значениями, поскольку работа идет то над одним, то над другим. Например:string pending_project( "Fantasia 2000, Firebird segment" );Функция-член swap() позволяет обменять значения двух строк с помощью вызоваcurrent_project.swap( pending_project );Для строкиstring first_novel( "V" );операция взятия индексаchar ch = first_novel[ 1 ];возвратит неопределенное значение: длина строки first_novel равна 1, и единственноеправильное значение индекса – 0.
Такая операция взятия индекса не обеспечиваетпроверку правильности параметра, но мы всегда можем сделать это сами с помощьюфункции-члена size():283С++ для начинающихintelem_count( const string &word, char elem ){int occurs = 0;// не надо больше проверять ixfor ( int ix=0; ix < word.size(); ++-ix )if ( word[ ix ] == elem )++occurs;return occurs;}voidmumble( const string &st, int index ){// возможна ошибкаchar ch = st[ index ];// ...Там, где это невозможно или нежелательно, например:}следует воспользоваться функцией at(), которая делает то же, что и операция взятияиндекса, но с проверкой.
Если индекс выходит за границу, возбуждается исключениеvoidmumble( const string &st, int index ){try {char ch = st.at( index );// ...}catch ( std::out_of_range ){...}// ...out_of_range:}string cobol_program_crash( "abend" );Строки можно сравнивать лексикографически. Например:string cplus_program_crash( "abort" );Строка cobol_program_crash лексикографически меньше, чем cplus_program_crash:сопоставление производится по первому отличающемуся символу, а буква e в латинскомалфавите идет раньше, чем o. Операция сравнения выполняется функцией-членомcompare(). Вызовsl.compare( s2 );284С++ для начинающихвозвращает одно из трех значений:•если s1 больше, чем s2, то положительное;•если s1 меньше, чем s2, то отрицательное;•если s1 равно s2, то 0.Например,cobol_program_crash.compare( cplus_program_crash );вернет отрицательное значение, аcplus_program_crash.compare( cobol_program_crash );положительное.
Перегруженные операции сравнения (<, >, !=, ==, <=, >=) являются болеекомпактной записью функции compare().Шесть вариантов функции-члена compare() позволяют выделить сравниваемыеподстроки в одном или обоих операндах. (Примеры вызовов приводились в предыдущемразделе.)Функция-член replace() дает десять способов заменить одну подстроку на другую (ихдлины не обязаны совпадать). В двух основных формах replace() первые двааргумента задают заменяемую подстроку: в первом варианте в виде начальной позиции идлины, во втором – в виде пары итераторов на ее начало и конец. Вот пример первогоstring sentence("An ADT provides both interface and implementation." );string::size_type position = sentence.find_1ast_of( 'A' );string::size_type length = 3;// заменяем ADT на Abstract Data Typeварианта:sentence.repiace( position, length, "Abstract Data Type" );position представляет собой начальную позицию, а length – длину заменяемойподстроки.
Третий аргумент является подставляемой строкой. Его можно задатьstring new_str( "Abstract Data Type" );несколькими способами. Допустим, как объект string:sentence.replace( position, length, new_str );Следующий пример иллюстрирует выделение подстроки в new_str:285С++ для начинающих#include <string>typedef string::size_type size_type;// найдемsize_typesize_typesize_typeпозицию трех буквposA = new_str.find( 'A' );posD = new_str.find( 'D' );posT = new_str.find( 'T' );// нашли: заменим T на "Type"sentence.replace( position+2, 1, new_str, posT, 4 );// нашли: заменим D на "Data "sentence.replace( position+1, 1, new_str, posD, 5 );// нашли: заменим A на "Abstract "sentence.replace( position, 1, new_str, posA, 9 );Еще один вариант позволяет заменить подстроку на один символ, повторенный заданноеstring hmm( "Some celebrate Java as the successor to C++." );string:: size_type position = hmm.find( 'J' );// заменим Java на xxxxколичество раз:hmm.repiace( position, 4, 'x', 4 );В данном примере используется указатель на символьный массив и длина вставляемойconst char *lang = "EiffelAda95JavaModula3";int index[] = { 0, 6, 11, 15, 22 };string ahhem("C++ is the language for today's power programmers." );подстроки:ahhem.replace(0, 3, lang+index[1], index[2]-index[1]);string sentence("An ADT provides both interface and implementation." );// указывает на 'A' в ADTstring: iterator start = sentence.