- Wstęp.
- Konstruowanie stringów.
- Iteratory.
- Operatory stringów.
- Metody stringów.
- Odsyłacze.
Witam. Standardowa Biblioteka Szablonów C++ (STL) oferuje nam typstring, posiadający wiele przydatnych metod, dzięki którym będziemy mogli czynić przeróżne cuda z naszym tekstem. Ale po kolei. W STL zdefiniowany jest szablon klasybasic_string, którego argumentem jest typ znaków, jaki będzie on przechowywał – możemy więc posiadać string, w którym znaki są typu char (8 bitów), typu wide char (16 bitów) lub innego. Szablon ten zawiera w sobie wiele ciekawych i przydatnych metod, które dają duże możliwości w manipulowani stringami. Zdefiniowanych zostało też kilka operatorów, aby praca z nimi była wygodniejsza.
Należy pamiętać, że tych stringów nie wolno mylić ze stringami, które są zakończone znakiem o kodzie 0 (NULL) – w stringach z STL zapamiętywana jest ilość aktualnie przechowywanych znaków, więc znak NULL nie jest potrzebny.
Typ, jakim będziemy się posługiwać, to wyspecjalizowany typ szablonu basic_string, w którym znaki są typu char:
C++
1 | typedef basic_string string; |
Do użytku oddany jest także typ, w którym znaki są typu wide char:
C++
1 | typedef basic_string wstring; |
Te typy mają także swoje własne metody oraz operatory, przydatne podczas pracy na nich.
Aby móc korzystać z tych dobrodziejstw, musimy włączyć do naszego programu nagłówek string:
C++
1 | #include |
Typy te znajdują się w przestrzeni nazwstd, więc przy definiowaniu zmiennych należy się posłużyć odpowiednim przedrostkiem:
C++
1 | std::string moj_tekst ; |
Dla wygody, na początku programu dodamy dyrektywę karzącą domyślnie dodawać przedrostek std:
C++
1 | using namespace std ; |
To tyle słowem wstępu ;]
>>Spis treści<<
String oferuje nam kilka konstruktorów (po dokładniejszy opis odsyłam doMSDN):
C++
1 2 3 4 5 6 7 8 9 | string(); string(const char* _Ptr, size_type _Count); string(const char* _Ptr); string(const string& _Right, size_type _Roff = 0, size_type _Count = npos); string(size_type _Count, char _Ch); |
_Ptr– ciąg znaków zakończonych znakiem NULL (argumentem nie może być sama wartość NULL)
_Count– liczba znaków, jakimi string ma być zainicjalizowany (pobierane z argumentów_Ptroraz_Right)
_Right– string, którego znakami ma być zainicjalizowany nasz string
_Roff– pozycja w_Right, od której należy pobrać_Countznaków
_Ch– znak, jakim ma być wypełniony string
Kilka przykładów:
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | string s1("Niezly hardkor." ,6) ; // s1 = "Niezly" string s2("Niezly hardkor.") ; string s3 = "abc" ;// można i tak, ale to jest już przypisanie, a nie inicjalizacja string s4(s2) ;// 4. konstruktor string s5(s2 , 7 , 7) ;// s5 = "hardkor" string s6(10 , 'u') ; // s6 = "uuuuuuuuuu" ; string s7 ; s7 = "unit1" ; |
Pytanie: co zawiera w sobie po utworzeniu string s4? Pustą wartość? Nie, gdyż domyślnie w trzeciem konstruktorze _Count =npos, które jest równe -1 i oznacza albo „nie znaleziono” lub „wszystkie znaki”, więc s4 zostanie zainicjalizowany wszystkimi znakami ze stringu s1.
>>Spis treści<<
Iteratory zostały stworzone specjalnie na potrzeby biblioteki STL. Można je przesuwać jak wskaźniki itp. Do wyboru mamy kilka iteratorów, jak np. iterator oraz reverse_iterator – pierwszy z nich pozwala odczytywać i modyfikować elementy wektora, a drugi pozwala na to samo, tylko, że w odwróconym wektorze. Wartość wskazywanego elementu pozyskujemy za pomocą operatora wyłuskania (*). Występują także wersje iteratorów, które mogą jedynie odczytywać wartości – const_iterator oraz const_reverse_iterator. Iteratory definiujemy w następujący sposób:
C++
1 2 3 4 5 | string str("kom") ; string::iterator mojIterator ; string::const_iterator mojStalyIterator ; |
Użycie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | mojIterator = str.begin() ;// ustawiamy iterator na 1. znak *mojIterator = 'd' ;// zmieniamy 1. znak na 'd' cout << "\n" << *mojIterator ; mojStalyIterator = str.begin() ;// staly iterator tez ustawiamy na poczatek // *mojStalyIterator = 'd' ;// blad! cout << "\n" << *mojStalyIterator ; // wypisujemy po kolei wszystkie znak, jeden pod drugim for (mojIterator = str.begin() ; mojIterator != str.end() ; mojIterator++) cout << "\n" << *mojIterator ; |
Istnieje wiele funkcji, które zwracają nam pozycję w stringu właśnie za pomocą iteratorów, jak np. begin().
>>Spis treści<<
Do wykorzystania mamy kilka operatorów:
= służy do przypisania stringowi nowej wartości:
C++
1 2 3 | string s ; s = "Niezly" ; // można też s = 'a' bądź s = s7 ; |
+= operator, za pomocą którego doklejamy do stringu nowy łańcuch znaków:
C++
1 | s += " hardkor." ; // s = "Niezly hardkor." |
[] operator, za pomocą którego odwołujemy się do poszczególnych znaków w stringu (są one numerowane od 0!).Uwaga:skutki podania nieprawidłowego indeksu (mniejszego od 0 bądź większego od maksymalnego) są niezdefiniowane, więc w razie niepewności należy stosować metodę at(), jednakże operator [] jest szybszy w działaniu od tejże metody.
C++
1 | s[0] = 'a' ; // odwołanie do pierwszego znaku; nie wolno s[0] = "a" ! |
!= sprawdza, czy string po prawej stronie operatora jest różny od tego z lewej strony.Uwaga: brana jest pod uwagę wielkość liter!
C++
1 2 3 4 5 | s = "unit1" ; if (s[0] != 'a') cout << "rozne od u" ; if (s != "unit5") cout << "rozne od unit5" ; |
== sprawdza, czy porównywane stringi są takie same.Uwaga: brana jest pod uwagę wielkość liter!
< porównuje dwa stringi i zwraca prawdę, jeżeli string z lewej strony jest „mniejszy”:
C++
1 2 3 4 5 6 7 8 9 | string str1("tes") , str2("test") ; if (str1 < str2) cout << "str1 mniejszy" << endl ; str1 = "TEST" ; str2 = "test" ; if (str1 < str2) cout << "str1 mniejszy" << endl ; |
Zobaczy komunikat dwa razy. Sprawdzane są tutaj kolejne znaki, a mniejszy jest ten znak, którego kod ASCII jest mniejszy, czyli porównując 'A’ oraz 'a’ wyjdzie, że 'A’ jest mniejsze ;] Poza tym, jeżeli string pierwszy ma taki sam człon jak drugi, ale jest od niego krótszy, to także jest on mniejszy.
> jak powyżej, ale tym razem prawda jest zwracana, jeżeli pierwszy string jest “większy”.
<= sprawdza, czy string z prawej strony jest mniejszy bądź równy temu z prawej strony operatora.
>= testuje, czy prawy string jest większy bądź równy od lewego.
<< wstawia string do strumienia:
C++
1 | cout << s ; |
>> wyjmuje dane ze strumienia i przypisuje je do stringu:
C++
1 | cin >> s ; |
+ operator ten łączy ze sobą dwa stringi:
C++
1 2 3 4 5 | s = str1 + str2 ; s = str1 + "tekst" ; // s = "Niezly" + " hardkor" ; tak nie wolno |
>>Spis treści<<
Do pracy na stringach mamy kilkanaście ciekawych metod i po kilka ich odmian. Oto one:
- append
- assign
- at
- begin
- c_str
- capacity
- clear
- compare
append
Funkcja ta dodaje do końca stringu inny:
C++
1 2 3 4 5 6 7 8 9 10 11 | string& append(const char* _Ptr); string& append(const char* _Ptr, size_type _Count); string& append(const string& _Str, size_type _Off, size_type _Count); string& append(const string& _Str); string& append(size_type _Count, char _Ch); string& append(InputIterator _First, InputIterator _Last); |
Parametry:
_Ptr– string zakończony znakiem NULL (tak zwany C-string),
_Count– określa, ile znaków ma zostać dodanych,
_Str– string, który ma zostać dodany,
_Off– wyznacza początek pod-stringu z_Str, który ma zostać dołączony,
_Ch– znak, jaki ma być dodany _Count razy,
_Firsti_Last– wyznaczają początek i koniec pod-stringu danego stringu, który ma zostać dodany.
Przykłady:
C++
1 2 3 4 5 6 7 8 9 | s = "Ala ma" ; s.append("kota, bo kot ma wszystkie sezony StarGate.") ; // s = "Ala ma kota, bo kot ma wszystkie sezony StarGate. " s = "Ala ma" ; s.append(" kota, bo kot ma wszystkie sezony Stargate" , 5) ; // s = "Ala ma kota" s.append(3 , '!') ; // s = "Ala ma kota!!!" |
—Spis metod—
Przypisuje stringowi nową wartość:
C++
1 2 3 4 5 6 7 8 9 10 11 | string& assign(const char* _Ptr); string& assign(const char* _Ptr, size_type _Count); string& assign(const string& _Str, size_type off, size_type _Count); string& assign(const string& _Str); string& assign(size_type _Count, char _Ch); string& assign(InputIterator _First, InputIterator _Last); |
Parametry:
_Ptr– przypisuje string zakończony znakiem NULL (tak zwany C-string),
_Count– określa, ile znaków ma zostać przypisanych,
_Str– string, który ma zostać przypisany,
_Off– wyznacza początek pod-stringu z_Str, który ma zostać przypisany,
_Ch– znak, jaki ma być przypisany _Count razy,
_Firsti_Last– wyznaczają początek i koniec pod-stringu danego stringu, który ma zostać przypisany.
Przykłady:
C++
1 2 3 4 5 6 7 | string str("Niezly hardkor!") ; s.assign(str , 7 , 8) ; // s = "hardkor" cout << s << endl ; s.assign(str.begin() , str.begin() + 6) ; // s = "Niezly" ; |
—Spis metod—
Zwraca referencję do znaku o indeksieloc:
C++
1 2 3 | char& at( size_type loc ); const char& at( size_type loc ) const; |
Kolejne znaki numerowane są od 0 do n – 1, gdzie n to ilość znaków w stringu.
Jedynym parametrem jest właśnie indeks znaku, który chcemy otrzymać. Metoda ta jest wolniejsza od operatora [], aleuwaga:używanie tej metody jest bezpieczniejsze od używania operatora [], gdyż sprawdza ona, czy indeks jest nieprawidłowy – czy nie jest mniejszy od zera bądź większy od maksymalnego indeksu, jeżeli tak będzie, zostanie wywołany wyjątek out_of_range.
Przykład:
C++
1 2 3 4 5 6 7 | string str("Niezly hardkor!") ; for (int i = 0 ; i < str.size() ; i++) cout << str << endl ; str[0] = 'n' ; |
—Spis metod—
Zwraca iterator do pierwszego znaku stringu (bądź do miejsca zaraz za końcem stringu, jeżeli ten jest pust):
C++
1 2 3 | const_iterator begin( ) const; iterator begin( ); |
Przykład:
C++
1 2 3 4 5 6 7 8 9 | string str("Niezly hardkor!") ; string::iterator it ; it = str.begin() ; cout << *it << endl ; // wypisujemy pierwszy znak, czyli 'N' cout << *(it + 5) << endl ; // przesuwamy się o 5 - znak 'y' |
—Spis metod—
Zwraca wskaźnik na zakończony znakiem NULL string (w stylu C). Nie można modyfikować tak przesłanego stringu, więc można go przesyłać jedynie do funkcji, które jako argumenty przyjmują const *char:
C++
1 | const char *c_str( ) |
Przykład:
C++
1 2 3 | string str("mojplik.txt") ; ofstream plik(str.c_str()) ;// konstruktor ofstream jako wymaga przeslania sciezki do pliku jako const char*, tutaj wkracza c_str() |
—Spis metod—
Zwraca maksymalną ilość elementów, jakie mogą być przechowywane bez konieczności zwiększanie rozmiaru zaalokowanej pamięci dla stringu:
C++
1 | size_type capacity( ) const; |
Przykład:
C++
1 2 3 | string str("Niezly hardkor") ; cout << str.capacity() << endl ; // zwroci liczbe 15 |
—Spis metod—
Usuwa wszystkie elementy ze stringu:
C++
1 | void clear( ); |
Przykład:
C++
1 2 3 4 5 | string str("Niezly hardkor") ; str.clear() ; cout << str ; // nie ukaze sie nam zaden tekst, bo str jest pusty |
—Spis metod—
Sprawdza, czy porównywane stringi są takie same, bądź czy jeden z nich nie jest większy/mniejszy od drugiego. Brana jest pod uwagę wielkość liter.Uwaga:małe litery są „większe” od wielkich, ponieważ ich kody ASCII są od większe. Zwracana wartość jest mniejsza od zera, jeżeli przesłany w parametrze string jest większy, zero, jeśli stringi są takie same oraz większa od zera, jeśli przesłany string jest mniejszy.
C++
1 2 3 4 5 6 7 8 9 10 11 | int compare(const string& _Str) const; int compare(size_type _Pos1, size_type _Num1, const string& _Str); int compare(size_type _Pos1, size_type _Num1, const string& _Str, size_type _Off, size_type _Count); int compare(const char* _Ptr) const; int compare(size_type _Pos1, size_type _Num1, const char* _Ptr) const; int compare(size_type _Pos1, size_type _Num1, const char* __Ptr, size_type _Num2 = npos) const; |
Parametry:
_Str– string, który ma zostać przyrównany,
_Pos1– indeks znaku w stringu, na rzecz którego funkcja została wywołana, od którego ma zostać rozpoczęte porównywanie,
_Num1– maksymalna ilość znaków ze stringu, na rzecz którego została wywołana funkcja, które mają zostać porównane,
_Num2– maksymalna ilość znaków z przyrównywanego stringu, które mają zostać porównane
_Off– pozycja znaku w porównywanym stringu, od którego ma zostać rozpoczęte porównywanie,
_Count– maksymalna ilość znaków ze stringu porównywanego jakie mają zostać porównane,
_Ptr– string w stylu C, który ma zostać porównany.
Przykład:
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | string str("") ; string str2("") ; // int compare(const string& _Str) const; cout << "Podaj pierwszy tekst:" << endl ; cin >> str ; cout << "Podaj drugi tekst:" << endl ; cin >> str2 ; int res = str.compare(str2) ; if (res < 0) cout << "Pierwszy string jest mniejszy od drugiego." << endl ; else if (res > 0) cout << "Pierwszy string jest wiekszy od drugiego." << endl ; else cout << "Stringi sa takie same." << endl ; // int compare(size_type _Pos1, size_type _Num1, const string& _Str); str = "www.unit1.pl" ; str2 = "unit1" ; // z www.unit1.pl zostanie wycięte "unit1" i porównane z "unit1", więc tekst "Takie same" zostanie wypisany if (str.compare(4 , 5 , str2) == 0) cout << "Takie same." << endl ; // int compare(size_type _Pos1, size_type _Num1, const string& _Str, size_type _Off, size_type _Count); str = "www.unit1.pl" ; str2 = "unit1.pl" ; // ze str zostanie porównane "unit1" ze stringiem wyciętym ze str2: "unit1", czyli znowu zobaczymy tekst "Takie same." if (str.compare(4 , 5 , str2 , 0 , 5) == 0) cout << "Takie same." << endl ; // te trzy funkcje zwroca wartosci 0, czyli znowu 3 razy zobaczymy tekst "Takie same." // int compare(const char* _Ptr) const; if (str.compare("www.unit1.pl") == 0) cout << "Takie same." << endl ; // int compare(size_type _Pos1, size_type _Num1, const char* _Ptr) const; if (str.compare(4 , 5 , "unit1") == 0) cout << "Takie same." << endl ; // int compare(size_type _Pos1, size_type _Num1, const char* __Ptr, size_type _Num2 = npos) const;[/ if (str.compare(4 , 5 , "unit1.pl" , 0 , 5) == 0) cout << "Takie same." << endl ; |
—Spis metod—
// z czasem będą się pojawiać nowy wpisy
>>Spis treści<<
- basic_string– opis szablonu basic_string w MSDN
- string– opis typu string w MSDN
- tutorial o STL– rozbudowany, godny uwagi anglojęzyczny tutorial o STLu
- dokumentacja STL– świetna, anglojęzyczna dokumantacja STL
>>Spis treści<<
Autor:Iskar