|
Sponsored link
phi-lab software
|
Lancuchy tekstowe (string).
Typ string nienalezy wprawdzie do STL, jest jednak wazna czescia biblioteki standardowej C++. Nie ma praktycznie rzecz biorac duzego programu, ktory w taki czy inny sposob by nie uzywal lancuchow tekstowych. Klasa string uzywa wewnetrznie takiego samego mechanizmu obslugi tablic typu char, jak to sie odbywa w C, poprzez wskaznik char*. Jednakze cale zarzadzanie pamiecia odbywa sie automatycznie, w tle.
Porownajmy dwa nastepujace programy, w ktorym z tekstow zawierajacych 'imie' i 'nazwisko' tworzymy tekst 'osoba' zawierajacy obie te dane.
Program w wersji C:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
const char* const imie = "Piotr";
const char* const nazwisko = "Pszczolkowski";
char* osoba = new char[ strlen( imie ) + 1 + strlen( nazwisko ) + 1 ];
strcat( strcat( strcpy( osoba, imie ), " " ), nazwisko );
cout << "Dane osoby: " << osoba << endl;
return 0;
}
Program w wersji uzywajacej klasy string:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const string imie = "Piotr";
const string nazwisko = "Pszczolkowski";
string osoba = imie + " " + nazwisko;
cout << "Dane osoby: " << osoba << endl;
return 0;
}
Typ string moze byc uzywany podobnie jak typy wbudowane int, double itd. Niektore operatory jak np. '+' dla dla string przeladowane.
Biblioteka standardowa udostepnia typ string poprzez typedef.
typedef basic_string<char> string;Co oznacza, ze tak naprawde bedziemy uzywac szablonu klasy basic_string, ktory jest zadaklarowany w nastepujacy sposob:
template< typename _charT, typename _Traits = char_traits<_charT>, typename _Alloc = allocator<_charT> >
class basic_string;
Pierwszy parametr _charT okresla typ uzywanych znakow. Dla zwyklych lancuchow tekstowych zostanie przekazany wbudowany typ char. Mozna takze przekazac typ np. wchar_t, co pozwala na obsluge zestawow poszerzonych znakow (16 bitowych).
Drugi parametr _Traits jest klasa pomocnicza, mowiaca klasie basic_string jak traktowac nalezy poszczegolne znaki, np. jak je porownywac. W ten sposob cechy charakterystyczne obslugiwanego zestawu znakow mozna umiescic poza klasa basic_string, co uniezaleznia ja od specyfiki stosowanego wlasnie zestawu.
Trrzeci parametr _Alloc odpowiedzialny jest za zarzadzanie pamiecia.
1. Wlasciwosci kontenera.
String mozna traktowac jako kontener dla znakow. Posiada wiele podobienst do klasy kontenerowej vector. Jednakze stosowanie vector<char> ma sens tylko w przypadku gdy chcemy przetwarzac poszczegolne znaki, natomiast string powolano do zycia po to aby moc latwo i przyjemnie przetwarzac cale ciagi znakow, lancuchy znakowe.
Klasa string spelnie zarowno wymagania ogolne dotyczace kontenerow, jak rowniez wymagania dotyczace kontenerow dwukierunkowych. Spelnia rowniez wymagania dotyczace kontenerow sekwencyjnych wlacznie z wymaganiami opcjonalnymi push_back(), operator[] jak rowniez at().
Ze wzgledu na wlasnosci kontenera string i faktu, ze iteratory tej klasy sa iteratorami dostepu swobodnego (and. random access iterators) w odniesieniu do klasy string mozna uzywac algorytmow biblioteki standardowej. Demonstruje to ponizszy program:
#include <cctype>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
char to_upper( char znak )
{
return toupper( znak );
}
int main()
{
const char text[] = "Miod to jest to co misie lubia najbardziej.";
//. 1
string str( text, text + sizeof( text ) - 1 );
cout << str << endl;
// 2. Globalny algorytm wyszukiwania
string::iterator it = find( str.begin(), str.end(), '.' );
if( it != str.end() ) {
cout << "Kropke znaleziono na pozycji: " << ( it - str.begin() ) << endl;
}
// 3. Globalny algorytm transformujacy
transform( str.begin(), str.end(), str.begin(), to_upper );
// 4. Globalny algorytm odwracania
reverse( str.begin(), str.end() );
cout << "Odwrocony tekst: " << str << endl;
reverse( str.begin(), str.end() );
// 5. Globalny algorytm zastepowania
replace( str.begin(), str.end(), ' ', '*' );
cout << "Spacje zamieniono na gwiazdki: " << str << endl;
// 6. Globalny algorytm sortowania.
sort( str.begin(), str.end() );
cout << "Posortowane: " << str << endl;
return 0;
}
Powyzszy program wyswietli na ekranie ponizsze informacje:
Miod to jest to co misie lubia najbardziej. Kropke znaleziono na pozycji: 42 Odwrocony tekst: .JEIZDRABJAN AIBUL EISIM OC OT TSEJ OT DOIM Spacje zamieniono na gwiazdki: MIOD*TO*JEST*TO*CO*MISIE*LUBIA*NAJBARDZIEJ. Posortowane: *******.AAABBCDDEEEIIIIIJJJLMMNOOOORSSTTTUZ
2. Typ size_type.
Typem numerycznym używanym przy określaniu pozycji znaku (indeks) w łańcuchu, jak i przy opisie rozmiarów, jest typ size_type.
Jest to typ całkowito-liczbowy bez znaku. Rozmiar typu jest zależny od implementacji.
Taki typ ma stała o nazwie npos.
static const size_type npos = static_cast<size_type>(-1);Stała ta pełni dwojaką rolę.
3. Konstruktory.
Poniżej przedstawiam możliwe konstruktory klasy string.
Są to wersje o tyle uproszczone, że nie pokazują parametru alokatora, który jeśli nie zostanie
podany przez użytkownika, zostanie zastąpiony wywołaniem alokatora domyślnego.
Poniższa tablica pokazuje przykłady użycia każdego z konstruktorów.
| Nr | Konstruktor | Wartość | Opis |
|---|---|---|---|
| 1 | string s1; |
Łańcuch pusty | |
| 2 | string s2( "abcxyz" ); |
abcxyz | Inicjacja łańcucha tablicą znakową. |
| 3 | string s3( "abcxyz", 3 ); |
abc | Inicjacja łańcucha 3-ma początkowymi znakami tablicy znakowej. |
| 4 | string s4( 5, 'X' ); |
XXXXX | Inicjacja łańcucha pięcioma znakami X. |
| 5 | string s5( s2 ); |
abcxyz | Inicjacja łańcucha innym łańcuchem. |
| 6a | string s6a( s2, 3 ); |
xyz | Inicjacja łańcucha innym łańcuchem począwszy od pozycji nr 3. |
| 6b | string s6b( s2, 3, 2 ); |
xy | Inicjacja łańcucha 2-ma znakami innego łańcucha począwszy od pozycji nr 3. |
| 7 | string s7( s2.begin(), s2.end() ); |
abcxyz | Inicjacja łańcucha innym łańcuchem przy użyciu iteratorów. |
Należy zwrócić uwagę, że nie można zainicjować łancucha jednym znakiem:
string s8( 'X' ); // Błąd
Wyjściem z tej sytuacji jest:
string s8( 1, 'X' ); // OK
4. Rozmiary.
Aby sprawdzić maksymalną liczbę znaków w łańcuchu, którą dopuszcza nasza implementacja, możemy użyć funkcji:
size_type max_size() const;Złożoność algorytmiczna tej funkcji jest stała O(1).
Aby otrzymać liczbę znaków które aktualnie zawiera łańcuch, możemy użyć jedną z poniższych funkcji:
size_type size() const; size_type length() const;Obie funkcje zwracaja tę samą liczbę, czyli liczbe znaków w łańcuchu. Wynik odpowiada end() - begin().
Aby sprawdzić czy łańcuch jest pusty, czy nie zawiera żadnych znaków, używamy funkcji:
bool empty() const;Funkcja zwraca wartosci 'true', jeśli łańcuch niezawiera żadnych znaków.
| Contact: piotr@beesoft.org |
(C) 2006-2008 beesoft.org Last modification date: 2008-06-29 |
Visitis counter: |