W poprzedniej części o klasie string zostały opisane podstawowe funkcje oraz operatory tej klasy. W tej części zostaną przedstawione pozostałe funkcje modyfikujące, które mogą znaleźć zastosowanie w wielu różnych projektach. Dotyczą one przede wszystkim wybierania fragmentów oraz przeszukiwania.
Najwygodniejszym sposobem na przypisywanie wartości zmiennej typu string jest użycie operatora przypisania =. Niemniej to samo można osiągnąć używając funkcji assign(). Przykładowo w celu przypisania zmiennej wartości równoważne są linijki:
Funkcja assign() może przyjmować różne zestawy argumentów. Na uwagę zasługuje tutaj jeszcze możliwość zapisania do zmiennej n razy tego samego znaku c. W cely przypisania do zmiennej wielokropka (złożonego z trzech kropek) wystarczy wpisać:
Część ta jest rodzajem przypomnienia z poprzedniej części jak można dołączać inny tekst do zmiennej. Przede wszystkim dobrze znanym operatorem + w (2.) formie ogólnej oraz (3.) skróconej:
Odpowiadającą operatorowi funkcją jest append(), które jako argument przyjmuje inny tekst w celu dołączenia go do zmiennej.
W celu dołączenia znaku do wybranej zmiennej string można korzystać z wymienionych wcześniej metod dołączania tekstu, ale można też skorzystać z funkcji push_back(), która dopisuje podany jako argument znak c.
Funkcją o przeciwnym działaniu jest pop_back(), która usuwa ostatni znak zapisany w zmiennej. Nie przyjmuje ona żadnych argumentów. Przed jej zastosowaniem należy upewnić się, że dana zmienna nie jest pusta, ponieważ może nastąpić wtedy nieoczekiwany wyjątek.
Bardzo często z całego wyrażenia przydałoby się skopiować tylko fragment. Do generowania nowego wyrażenia na podstawie konkretnego fragmentu służy funkcja substr(), która zwraca fragment zaczynający się od podanej pozycji pos o długości len. Przykładowo, aby wybrać z wyrażenia "czerwony zielony niebieski" słowo "zielony" należy wpisać:
Usunąć cały tekst w zmiennej można na dwa sposoby: pierwszy polega na przypisaniu zmiennej pustego łańcucha tekstu. Jednak istnieje prostsze rozwiązanie. Mowa tu o funkcji erase(). Funkcja nie zwraca żadnej wartości i nie przyjmuje żadnego argumentu.
W przypadku próby usuwania konkretnych znaków z tekstu warto zastosować funkcję erase(). Pierwszy zestaw argumentów jaki można jej przekazać to pozycja pos od której ma zostać usuniętych len znaków. Usunięte zostaną wtedy wszystkie znaki z przedziału [pos, pos + len). Przykładowo, aby usunąć z tekstu "zostaw usun" fragment " usun" należy wpisać:
W celu wstawienia innego tekstu na konkretną pozycję w innym tekście można skorzystać z funkcji insert(), która jako argumenty przyjmuje pozycję pos oraz tekst do wstawienia str. Przykładowo, aby na początek wyrażenia "informacja" dopisać "tajna " wystarczy (3.) linijka:
Zastępowanie w C++ polega na wskazaniu fragmentu tekstu, który ma zostać zastąpiony przez inny tekst. Stosuje się do tego funkcję replace(), która kolejno przyjmuje pos - pozycję pierwsze znaku do zastąpienia oraz len - ile znaków ma zostać zastąpionych, trzeci argument str - określa tekst do wstawienia zamiast wybranego fragmentu znaków o indeksach [pos, pos + len).
W celu zamiany w wyrażeniu "a d c.." fragmentu " d" na " b" należy zapisać:
Jej działanie różni się od innych funkcji replace() w innych językach, gdzie podaje się dwa wyrażenia tekstowe i wystąpienie pierwszego wyrażenia jest zastępowane drugim.
Przypuśćmy, że jest pewne wyrażenie tekst w którym istnieje potrzeba znalezienia określonych informacji. Klasa string zawiera kilka funkcji, które pozwalają na szybkie wyszukanie danych w dowolnym miejscu.
Jedna z nich to find(), która szuka podanego wyrażenia str w zmiennej. Istnieje jej analogiczna wersja rfind(), która też szuka wyrażenia str w zmiennej, ale od końca. Wynikiem jest indeks od którego rozpoczyna się podane wyrażenie str. W przypadku nie znalezienia funkcje zwracają stałą string::npos, która wynosi -1.
Przypuśćmy, że tekst to "bardzo szybko dane sa wyszukiwane". Wtedy dla podanych argumentów zostaną zwrócone następujące dane:
str | find(str) | rfind(str) |
---|---|---|
sz | bardzo szybko dane sa wyszukiwane | bardzo szybko dane są wyszukiwane |
7 | 24 | |
dane | bardzo szybko dane sa wyszukiwane | bardzo szybko dane są wyszukiwane |
14 | 14 | |
abc | bardzo szybko dane sa wyszukiwane | bardzo szybko dane są wyszukiwane |
string::npos | string::npos |
Warta uwagi jest funkcja find_first_of(), która przyjmuje jako argument znaki zapisane jako tekst. Jej zadaniem jest znalezienie pierwszej pozycji któregokolwiek z wymienionych znaków. Analogicznie działa funkcja find_last_of(), która wyszukuje od końca. W przypadku nie znalezienia obie funkcje zwrócą string::npos.
Przypuśćmy, że tekst to "abrakadabra". Wtedy dla podanych argumentów zostaną zwrócone następujące dane:
str | find(str) | rfind(str) |
---|---|---|
abc | abrakadabra | abrakadabra |
0 | 10 | |
k | abrakadabra | abrakadabra |
4 | 4 | |
mno | abrakadabra | abrakadabra |
string::npos | string::npos |
Użytkownik bywa omylny, a programista powinien być tego świadom. Dla komputera nie zawsze jest wszystko jedno jakie dane otrzyma. Bardzo często wprowadzony tekst należy sprawdzić czy zawiera dane tylko konkretnego typu. W przypadku niespełnienia warunków program może poprosić o wprowadzenie innych danych, albo dokonać korekty danych usuwając zbędne dane.
Do sprawdzania czy dane wyrażenie składa się tylko z poprawnych znaków można skorzystać z funkcji find_first_not_of() tym razem działanie tej funkcji polega na tym, aby podać indeks pierwszego znaku, który nie występuje w przekazanym wyrażeniu str. Tak samo jak poprzednio istnieje funkcja analogiczna find_last_not_of(), która poszukuje od końca. W przypadku, gdy wszystkie znaki z zmiennej występują w str to program zwróci str::npos.
Przypuśćmy, że tekst to "abc1234_xyz". Wtedy dla podanych argumentów zostaną zwrócone następujące dane:
str | find(str) | rfind(str) |
---|---|---|
abcxyz | abc1234_xyz | abc123_xyz |
3 | 7 | |
_., | abc1234_xyz | abc1234 xyz |
0 | 10 | |
_abcxyz1234 | abc1234_xyz | abc1234_xyz |
string::npos | string::npos |
Jak można zauważyć klasa string dostarcza bardzo dużo przydatnych funkcji. Oczywiście nie trzeba wszystkich znać na pamięć, ale z pewnością świadomość ich istnienia mogłaby okazać się bardzo pomocna. Proponuje zajrzeć do kodów źródłowych, aby prześledzić lekcję jeszcze raz. Po powtórzeniu warto wykonać dołączone zadania.
Poproś użytkownika o podanie imienia i nazwiska. Następnie zamień obydwa wyrażenia miejscami. W rozwiązaniu nie wolno wykorzystać operatora łączenia, ani funkcji append(). Przykładowo jeśli użytkownik wprowadzi:
program wypisze na ekran:
Napisz program, który wczyta od użytkownika dwie linijki tekstu. Pierwsza linijka będzie zawierać tekst w którym wszystkie znaki z drugiej linijki powinny zostać zastąpione znakiem kratki #. Przykładowo jeśli użytkownik wprowadzi tekst "abrakadabra" i "abc" program powinien wypisać:
Napisz program, który zapyta użytkownika o ulubioną liczbę, a następnie wczyta od użytkownika linijkę tekstu, a program sprawdzi czy wczytane wyrażenie jest liczbą. W przypadku, gdy wyrażenie jest liczbą powinien wypisać np. "Twoja ulubiona liczba to 2!", a w przypadku, gdy wyrażenie nie jest liczbą program powinien poprosić o podanie liczby jeszcze raz. Oto przykładowy zapis na konsoli: