Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 147
Текст из файла (страница 147)
Для шаблонов с несколькими параметрами зто приводит к неудобству заееиси, поскольку параметры шаблона повторяются. С другой стороны, использование конкатенации понятно и удобно. Например: кГГЕпусотр!еГе лптеЗ (солзгзЕЕЕпуй/егкЕ лате, сопзгк1еулуй/атйу пате) 20.3. Тип Ьаз(с з!пп0 яие Муре/!амМ 1ая! о/(сотМСЬ*р,кие Муре! = арок) соля1; вие Муре)!пмМ 1ая1 о~'(СЬ с, яие 1уре1= пров)соак1, // аоиск символа, ко ~араго нет в аргументе: я(ге Муре/Млб /ия! по! ог (сопя! ьая(с яме!луйк, я!ее 1уре м = О) сот!; яие Муре/мас( )!гв1 ао1 о/(соая1СЬ" р,в(ве 1уре !,яие Муре п)сопя1; к!ее Муре/Мпм( )!гв! поМ о/(сопк1СЬ'р, в!ге Муре !'= О) сопя!; вие !урежете! /мгя1 по1 о/(Сбс, в(ее Муре(=О)сопке, // поиск с~и!вола, кол!араго нет в аргументе, накипая с конно: яие Муре)!пб 1ая1 по! о/(сопя! ЬавМс вгг!луйк,к(ве !уре1 = прок)сот!; яие Муре/аи! !аяйн ло1 о/(соля! СЬ*р, к!ее Муре(, вие !уреа) соля!; в!ге Муре/мам! !агкМ по1 оХ(сопя! СЬ'р,яие 1урем= пров) сопя1; яие Муре/млсМ !ав! по1 о/(Сбс,в!ее !урем= прок) сот1; Все это константнмяс члены.
То есть они существуют для тото, чтобы локализовать подстроку для какого-либо использования, но не изменяют значения строки, к которой применяются, Значение функций Ьая(с я1г(п~Япс[можно понять по их аналогам среди универсальных алгоритмов. Рассмотрим пример: пои ( вМг!ау яягассс(сне"; //! 1=2 к[2)=='с' йй к[3)=='4' //11=4 к[4)=='с' йй к[5)=='4' //13=! к[!)=='с' // !4=5 к[5~=='ММ' 0 ~5=0 я[О)!='с' йй я[О)!='с(' // ~б=б к [б)!='с' йй к[б) 1='м(' в!г!лр яие !уре !! = вЯамм ('смм"~! я1г(пу. яие 1уре !2 = кг/ММмсМ ( ссМ'~; я!пауля!ке Муре !3 = в/!пб ММгк1 оХ('смМ"), кМг!пу:.к!ее !уре 14 = к,!!ам! 1ая1 о/("смМ'), яМг!щ:.я!ее Муре !5 = в/Млм( 12гв1 по! о/('смМ'), яМг!пц:я!ее !уре!б= вЯпмМ 1ая! по1 о~:('ссМ'), ) Если такая функция/Мпс[ () не находит ничего, она возвращает проз, что означает за- прошенную позицию символа. Если прок используется как позиция символа, сгене- рируется ои1 о/ галие Ц 20.3.5).
20.3.12. Замена Когда поз!линя в строке определена, можно изменить отдельный элемент при помощи его индекса или замени~ь целую подстроку новыми символами при помо!пи функции гер!асе (): Метр!а1е<с!тв СЬ, с!акк Тг = сбаг Мга11в<СЬ>, с!аяк А=аИосаМог<СЬ» с!аяя Ьаягс я!Мбпу( риЬ!!с: //...
//замена(1'МЬМк)Д, [*МЬ!к)[гнп) [другииисимволалш: бак!с вМгМлуй сер!осе(к!ве Муре й нее !Орел,соля! ЬакМс всгиц,й в!к); бак!с яМг!пуйгер!асс(к!ее Муре Скис 1уре п, соаяМ баки вМг(пуйя,яие Муре 12, яие Муре п2); Ьав(с я1ппдйгер!асе (вие !урей кис 1уреп, сопя! СБ*р, яие Муре л2); 662 Глава 20. Строки ьазьс и1г!ау& гер!асе (и!ее 1уре е, иьке 1уре а, сопи! сь*р); Ьазьс и!пну& гер!асс (иске туре!, и!зе 1уре а,иске 1уре а2, СЬс); Ьаи!с я!пну& гер!асе (!ЕегаЕог 1, йега1ог !2, соля! ЬаяЕс к!пну& яЕг), Ьаи!с иЕг!ау& гер!асс(дега1оге,!!его!о~ е2, сони! СЬ*р,и!ге !урез,'; Ьаясс иа !ну& гер!асе (е!его 1ог Ь еЕегаЕог е2, соая1СЬ'р), ьаи!с к1г!ееу& гер!асе (йега1ог !, йега1ог!2, и!ее 1уре а, сь с); Еетр!аЕе<с!азз 1аьЬаздс и!пну& е ер!асс (Мее аЕог е, йегаЕое !2, 1л 1, 1а !2), // удаление силволов нз пнроки (кзалнена ни еелеь/е Ьаясс я1 пну& егаяе (и!ке Еуре 1=0, зсзе гуре и =арок) езегаЕог егояе УЕега1ог !!; !Еега1ог е газе (пега 1ог/тяЕ, Пега !ог! аиЕ), со!д с!еаг (), // удал зев! все символы Отметим, что число символов в новой строке не обязательно должно бьжь тем же, что было в строке раньше.
Размер строки изменяется, чтобы принять в себя новую подстроку. В частности, егаие () просто удаляет подстроку и соответственно изменяет размер строки. Например: оон1/'() тпзу з = 'ноя расскажу зту историю, давя е если вы ей не поверите', и.егаие (О, 3)! //удалзел 'но и.гер1асе (я/!ад('даже" ),4,'лишь*), и гер!асс (я(!ад('не ),2,"); // удаление валеной на" Лростой вызов егаяе () без аргументов превратит строку в пустую строку. Эта операция для универсальных контейнеров называется с1еаг () (~ 163.6). В своем разнообразии функции гер1асе () нс уступают присваиваниям.
В конце концов, гер1асе () — зто присвапванис нового значения подстроке. 20.3.13. Подстроки Функция зибиуг () позволяет вам указать подстроку, задав позицию и длину: 1етр!асе<с!аки СЬ, с1аии Тг = сдаг 1гапя<СЬ>, с!азз А = а!!оса!ог СЬ» с!аяк Ьаяес иЕг!ау( риЬ!!а 0- // адрес подстроки: Ьакзс игг!пукидиЕг(я!ее Еурее=д;яьзе !урез=прок) соля!, оо!д с!еаг (); // удаляет все аьнволн Функция киЬи1г () — это просто способ прочитать час~ь строки. С друтой стороны, сер!псе () позволяет вам вписать что-лнбо в подстроку, И та, и другая используют низкоуровневую позпцшо н указанное число символов. Однако/епеЕ () позволяет нам находить подстроку по ее значению, Все вместе они дают возможность определить подстроку, которую можно использовать как для чтения, так и для записи: 20,3.
Тип (зав)о Ыпп0 1етр!а1е<с)аяя Сй> с!аяя Вая!с зиЬз1г!пу ( ри61!с: 1урег!е~1урепате Ьаис яггту<СЬ>сяеге 1уре иге 1уре; Ваис кийк!ггпу(Ьаис згппу<СЬ>йк, веге 1уре!,зтге 1уреп), Вая)с яиЬз1г!пу (бак!с кгг1пу<СЬ>из, сопк1 Ьаяс згг!пу<СЬ>ь в2); Вав)с кибиг!пу(Ьаяш кггту<СЬ>ь к, сопИ Сй* р); Ваис зибк1ппуйорега1ог= (сопв1 Ьаь!с згппу<СЬ>ь), Ваяс яибкгппуйорегагог= (сопя! Вав1с зибз1ппу<СЬ>й) Вая)с кибкгг1пдЯ орегагог= (сопя! Сй"); Ваяк вийк!с!пуз орега!ог= (Сй); //зь).к(сгп 1) //>2 вь // 'р в ь // запись через "рь // ч а!ение из *ря орега1ог Ьаяк зьг!П<СЬ> () сопИ; орегагог Сй* () сонь!; риоа1е: баяс вгг(пу<СЬ>" рз; ваге 1уре роя; яге 1уреп, ); Реализация лостаточно тривиальна. Например: гетр 1а 1е<с1 акв Сй> Ваис киЬИппу<СЬ>:Ваяя зиЬк1ппу(Ьаис я1г(пу<СЬ>! к,сопИЬаяс згг(пу<СЬ>ь к2) : рз (аз), п (я2 1епугй ()) ( роя = я|те! (я2); 1етр1а1е<с(азя Сй> Воя!с вийя! ппу<СЬ>г, Вак1с вибкггшу<СЬ>сорегагог= (сопк1 Ьаис згппу<СЬ>«я) ( рк — >гер!асе (роь, и, я); ге1игп "1Мз; // запись через указатель 'рк 1етр!аге<с1аяя Сй> Ваис зиЬьочпу<СЬ> сорега1ог баяс з1пп у<С!г () сопя! ( ге1игп Ьая)с я1г!пу<СЬ> ( рз роя п); //копирование из*рь ) Если ь2 не найдена в ь, рок будет ранен прок.
ГГопытки прочитать или записать по такой позиции будут генерировать ои1 о/' гавре Я 20.3.5). Этот Ваис кибз1г!пд можно использовать так: 1урес!е~Ваз!с зибк1гтпу<сйаг> Бибягг!пу, оо)с(Я ( в!с!пуз = Наша Маша громко плачет'; Бибягг!пу(я, 'Машай = 'Миша', Бибзгппу(з, "громко") ="никогда не"; зггг1пуя2 ="Наш" + Яибвтг1пу(в, я/1пд (' '), згг1пуспроя) Естественно, было бы гораздо интереснее, если бы функция Яибз1ппд умела искать по образцу Гф 20В(7)).
Глава 20. Строки 664 20.3.14. Размер и емкость Функции, связанные с выделением памяти, очень похожи на аналогичные функции для векторов: (етр(а1е<с!ази СЬ, с1пиз Тг = сбаг 1гааи<СЬ>, с!аы А = а!(оса(ог<СЬ» с1аы батс з!Ппу( риб1(с; !(- О размер, емкость и пр. (подобная 1б.З.В) и(яе 1уре и(ие () сопи; О число сииеолоя (Я 20.3А) исае 1уре тах яссе () сопи; ((льаксииольная длина строки з!зе !уре (епу(Ь () сопи1 ( ге!игп и!зе (); ) боо! етр(у () сопи(( ге(ига зые () == д; ) оо(д геиее (зьее 1уреп, СЬ с); по(д гез(зе (иее (уре и) ( геи!зе (и, СЬ ()), ) исее 1уре сараеву () сопз1; ,(( как для ьес(ог: у" (6.3.8 ооЫгезегие(и(ее 1урегез агу=0); ((какдляоес1ог: я (б3.8 а!1оса1ог (уре уе! а!(оса!ос () сопи!; ); Вызов геяегое (гея агВ) генерирует (епу(Ь еггог, если гея аг(д>тах я(ге ().
20.3.15. Операции ввода/вывода Одно из главных применений строк — использование их. как приемника при вводе и как источника при выводе. Операторы ввода и вывода для Ьая(с и!г(пя'предоставляются <я(г(пд> (но це <(оз1геат>): (етр(п(е<с(ази СЬ, с(аия Тг, с!оиз А> бапс (я!геат<СЬ, Тг>й орега!ог> (базис (и1геат<СЬ, Тг>й, баас и1г!пу<СЬ, Тг, А>й), (етр(а1е<с(аиз СЬ, с(аяи Тг, с1аииА> Ьпедс ои!гепт<СЬ, Тг>й орега!ог«(баи!с ои(геат<СЬ, Тг>й, Ьаяс и(г!пе<СЬ, Тг А>ц; (етр(а(е<с(аии СЬ, с1азз Тг, с(пии А> баедс (и1геат<СЬ, Тг>йуе11!пе(Ьаи!с гз!геат<СЪ, Тг>й,батс и(Ипу<СЬ, Тг А>й, СЬсо(), (етр(а1е<с(аия СЬ, с1пы Тг, с!аизА> баас !и!геат<СЬ, Тг>й де(1(пе (базгс (и(геат<СЬ, Тг>й, батс Ыппу<СЬ, Тг, А>й), Оператор «пишет строку в оя!геат Я 21.2.1).
Оператор» считывает слово, ограниченное <символом-разделителем> (чгйгезрасе) Я 3.6, ч 213.1), в указанную строку, расширяя ее по мере необходимости, чтобы вместить все слово. Первые символы-разделители пропускаются, а завершающий символ-разделитель в строку нс вводится. Функция де!1(пе () считывает строку, оканчиваюгцу!ося символом ео1 (спд о1 1)пе— конец строки) в указанну!о строку, по мере надобности расширяя последнюю. Если не указан аргумент ео1, ограни ппелем считается символ новой строки — 'лп'. Ограничитель пз потока удаляется, но в строку не вводится. Поскольку, чтобы вместить ввод, я1г(пу расширяется, не имеет смысла оставлять символ конца строки в потоке или считать символы, как зто делают де( () и де!1(пе () для символьных массивов Я 21.3А), 20.4.
Стандартная библиотека С 20.3.16. Перемена местами Как и для векторов (9 16.3.9), функции яшар () для строк могут о!газ аться гораздо эффективнее, чем универсальные алгоритмы, поэтому для них введены специальные версии: !етр1а!е<с!азя СЬ, с!азз Тг, с!азз А> ив!д итар (Ьаз!с ягг!ау<СИ, Тг А>й, базтс я!г)ау<СИ, Тг А>Ц; 20.4.1. С-строки Функции для манипулирования С-строками находятся в заголовочных файлах <я1г!пу. Ь> и <ся1г!пьт>; айат я!геру (сйат р, сапз1 сЬаг* у); //копирование из гавр (включая конег! строки) сйаг'з1гса1(сйаг* р, сопя! сйат' у); // добавление у в р !включая конец сгпроки) сйаг'и!гаеру (сйаг'р, сопит сйаг'г), тп1 и); // копиргтвггние и силгволав из у в р сЬаг'я1гпсат (сйпг' р, саля! сйаг' г1, тп1 и); О добавление и символов из д в р //длина р (не считая конца мароки) //сравнение р и г) // сравнение первака сшгволов згее 1к!г!еп (свпя1 сйаг* р); т1 я!гетр (саля! сйат" р, сопя! сйа!" у); т1 з !гает р (сот!я! сЬ аг' р, сопя! сЬаг* у, !и! п); // поиск первого вхождения с в р сйаг' я1гсйг (сйаг* р, 1п1 с); свпя1 сйат" з1гсйг (сапя1 с!ии р, !л! с); // поиск последнего вхождения с в р сйаг* я)ггсйг (сЬаг' р, 1п1 с); свпз1 сйат и1ттсйг (сапз1 сйаг'р, тп1 с); // поиск первого вхождетт у в р сйаг' я!гя)г (сйаг' р, сапз1 сйаг' у); сопи 1сйаг' кок!г(сапи1сйаг' р, свпк1 сйаг' у); // поиск в р первого вхождения О символа из г) сйпг* я1грйгй (сйагы р, свпя1 сйат" д); сопя! сйаг' я!грЬгй (свпя1 сйаг' р, саля! сйаг" д), я!ге 1я!гкрп (саля! сйаг" р, сопя! сйаг' д); я!ее 1и!гскрп (сопз1 сйаг'р, сопзтсйат" д); //числосимвалов врдолюбого // символа, не встречающегося в у // виска симвояов в р дв любгтго // символа, встреча юи!егося в д 20.4.