Klasa std::string
String u programskom jeziku C je niz znakova varijabilne duljine koji završava nul-znakom
(\0)
koji označava kraj stringa. Najčešće se alocira dinamički, a kretanje kroz njega se
vrši pomoću pokazivača na prvi element, uporabom pokazivačke aritmetike.
U jeziku C++ stringove iz jezika C (C-stringove) zamijenjuje klasa std::string
koja brine o dinamičkoj alokaciji i dealokaciji niza znakova te nudi veliki broj metoda
za rad sa stringovima.
Klasa string
je ustvari specijalizacija predloška klase basic_string<T>
. U imeniku std
imamo
ove aliase:
namespace std{
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
}
Nizovne konstante, kao na primjer
auto x = "OP(C++)";
su C-stringovi, odnosno nizovi znakova završeni nul-znakom. Tip varijable x
se deducira kao const char *
.
Najčešće ih možemo koristiti tamo gdje se traži std::string
zato što postoji implicitna konverzija
iz C-stringa u std::string
.
Definicija i inicijalizacija stringova
Da bismo koristili klasu string iz standardne biblioteke moramo uključiti zaglavlje string.
#include <string>
using std::string;
String možemo inicijalizirati na različite načine. Na razini implementacije to znači da klasa string ima više verzija konstruktora. Ovdje su dani neki od njih:
string s1; // Konstruktor bez argumenata konstrira prazan string
string s2(s1); // s2 je inicijaliziran kopijom stringa s1
string s3("ime i prezime");// s3 je inicijalizira konstantnim stringom
string s4(10,'x'); // s4 je inicijaliziran sa 10 znakova 'x'
-
Nul-znak (
\0
) nema posebno značenje ustd::string
klasi istring
ga može sadržavati kao i svaki drugi znak. -
Ako nekoj funkciji koja uzima C-string treba predati
std::string
onda koristimo metoduc_str()
koja vraća reprezentaciju stringa kao niza znakova završenog nul-znakom:
void f(char * str){
// ...
}
// ...
std::string mystring;
// ...
f(mystring.c_str());
Povratna vrijednost c_str()
funkcije je garantirano ispravna samo do poziva prve
operacije na stringu koja ga može promijeniti.
Čitanje i pisanje stringova
Za čitanje stringova s tastature (standardni ulaz, std::cin) i njihovo ispisivanje na ekranu (standardni izlaz, std::cout) koristimo operatore << i >> kao u ovom primjeru:
cin >> s1;// Učitavanje stringa limitiranog bjelinama
cout << s1 << endl; // Ispis stringa
Prilikom učitavanja preskaču se početne bjeline, a učitavanje prestaje s prvom bjelinom. Operacije čitanja i pisanja mogu se ulančavati kao u ovom primjeru:
cin >> s2 >> s3;// Čita prvo s2, a zatim s3.
cout << s2 << s3 << endl; // Ispisuje prvo s2, a zatim s3.
Želimo li učitavati s ulaza sve dok ne naiđemo na kraj ulaznih podataka (end-of-file) trebamo koristiti sljedeću konstrukciju:
while(cin >> s1)
cout << s1 << endl;
Ukoliko dođe do greške pri upisu, ili smo došli do kraja ulazne datoteke,
cin >> s1
će vratiti false i tada izlazimo iz while petlje. (Pod Linuxom/Unixom treba upisati
Return i Ctr-D kao znak za kraj datoteke.)
Ulazni operator ne može pročitati string koji sadrži bjeline pa je stoga korisna funkcija getline koja će pročitati čitavu liniju, sve do znaka za prijelaz u novi red koji se pročita i odbacuje. Na primjer,
while(getline(cin,s1))
cout << s1 << endl;
Pri ispisu smo morali dodati endl jer znak za prijelaz u novi red nije učitan u s1.
Operacije na stringovima
U sljedećoj tabeli su navedene neke operacije koje možemo vršiti nad stringovima.
|
Vraća true ako je string prazan; inače false |
|
Vraća broj znakova u |
|
Vraća referencu na znak na poziciji |
|
Isto što i |
|
Vraća string koji je jednak konkatenaciji stringova |
|
Zamijenjuje string |
|
Ispituje jednakost stringova |
|
Relacijski operatori provjeravaju leksikografski poredak. |
Nadovezivanje jednog stringa na drugi (konkatenacija) vrši se pomoću operatora zbrajanja. Ti su operatori (+, +=) redefinirani u klasi string kako bi mogli biti primijenjeni na stringove.
string str1 = "AAA";
string str2 = "BBB";
string str3 = str1 + str2;// Konkatenacija dvaju stringova
string str4 = str3 + "\n";// Konkatenacija stringa i konstantnog znakovnog niza
str1 += str4; // Dodavanje stringa str4 na str1
for(string::size_type i=0; i < str4.size(); ++i)
if( str4[i] == 'B') str4[i] = 'X';
Indeks koji treba koristiti za kretanje kroz string je tipa string::size_type
.
String predstavljaja jedan sekvencijalni spremik, specijaliziran za držanje znakova. Kao i kod vektora,
znakovi se čuvaju na uzastopnim lokacijama u memoriji što dozvoljava efikasno indeksiranje niza. String je stoga vrlo
blizak spremniku vector
i podržava operacije koje podržava vector
.
Indeksirane operacije
String podržava operacije insert
, erase
i assign
koje rade s iteratorima ili
parovima iteratora, ali nudi i paralelne metode koje rade s indeksima umjesto iteratora. Te su operacije dane u sljedećoj tabeli
u kojoj su pos
i pos2
indeksi:
|
Ubacuje |
|
Ubacuje kopiju stringa |
|
Ubacuje |
|
Ubacuje |
|
Ubacuje kopiju znakovnog niza na koji pokazuje |
|
Zamijeni |
|
Zamijeni |
|
Zamijeni |
|
Zamijeni |
|
Obriši |
Sve operacije vraćaju referencu na s
.
Neki primjeri su dani ovdje:
string s1("Dobar dan.");
string s2;
s2.assign(s1,6,3); // s2 = "dan"
s2.assign(s1,2,string::npos); // s2 = "bar dan."
s2.assign(3,'v'); // s2 = "vvv"
s2.insert(0,s1); // s2 = "Dobar dan.vvv"
s2.insert(10, s1, 6, 4); // s2 = "Dobar dan.dan.vvv"
s2.insert(0, 3, 'x'); // s2 = "xxxDobar dan.dan.vvv"
s2.erase(8,4); // s2 = "xxxDobar.dan.vvv"
std::string::npos
služi kao oznaka za kraj stringa.
Substringovi
Iz svakog stringa možemo izvući odgovarajući podstring pomoću substr
operacije.
Operacija vraća kopiju novostvorenog stringa.
|
Vraća string koji sadrži |
|
Vraća string koji sadrži znakove od pozicije |
|
Vraća kopiju od |
append i replace
Postoji više preopterećenih verzija funkcije append
ifunkcije replace
.
Funkcija append
dodaje znakove na kraj stringa; funkcija replace
zamijenjuje raspon znakova
drugim znakovima. Pri tome zamjena jednog skupa znakova drugim znači da se prvi skup briše (erase
)
i zatim se na to mjesto ubacuje novi skup znakova (insert
).
Funkcije append
i replace
razlikuju se po načinu na koji se zadaje raspon
znakova koje ubacujemo, a
funkcije replace
se razlikuju i po načinu zadavanja raspona elemenata koji se izbacuju (zamijenjuju)
iz stringa. Metode su dane ovdje:
|
Dodaj |
|
Izbaci |
|
Izbaci znakove u rasponu određenom s iteratorima |
Argumenti args
, kojim se zadaju rasponi, dani su u ovoj tabeli:
|
String |
|
Najviše |
|
Znakovni niz na koji pokazuje |
|
Najviše |
|
|
|
Znakovi u rasponu određenom iteratorima |
Primjer:
string s3{'a','b','c'}; // s3 = "abc"
s3.append("defg",0,3); // s3 = "abcdef"
s3.append(2, 'g'); // s3 = "abcdefgg"
vector<char> vec{'h','i','j'};
s3.append(vec.begin(), vec.end()); // s3 = "abcdefgghij"
s3.replace(0,6,"--"); // s3 = "--gghij"
auto s4 = s3.substr(5); // s4 = "ij"
s3.replace(2,5,s4); // s3 ="--ij"
find
Imamo šest verzija funkcija za pretraživanje stringa. Svaka od tih funkcija vraća string::size_type
tip koji predstavlja indeks pozicije na kojoj je nađena tražena vrijednost. U slučaju negativnog rezultata
pretrage vraća se string::npos
vrijednost, koja garantirano nije dobra vrijednost indeksa.
Svaka od funkcija pretraživanja ima više preopterećenih varijanti koje se razlikuju po načinu na koji je zadano ono što se traži.
|
Nađi prvo pojavljivanje |
|
Nađi zadnje pojavljivanje |
|
Nađi prvo pojavljivanje bilo kojeg znaka iz |
|
Nađi zadnje pojavljivanje bilo kojeg znaka iz |
|
Nađi prvi znak u |
|
Nađi zadnji znak u |
Argument args
koji se traži dan je ovoj tabeli:
|
Traži znak |
|
Traži string |
|
Traži znakovni niz završen nul-znakom na koji pokazuje |
|
Traži prvih |
Primjer:
string s5("Molim da ne koristite preopterećenje operatora i funkcija u svom programu.");
auto n = s5.find("preopterećenje"); // n = 22
n =s5.find("i", 22); // n = 48
n = s5.rfind("preopterećenje"); // n = 22
n = s5.find_first_of("kd"); // n=6, nalazi "d"
n = s5.find_first_not_of("Mmkdol"); // n=3, nalazi "i"
n = s5.find_last_not_of("Mmkdol"); // n=74, nalazi "."
compare
Za uspoređivanje stringova možemo koristiti operatore ==, !=, <, >, <=
i >=
.
Svi oni vrše leksikografsko uspoređivanje, znak-po-znak. To znači da se uspoređuju odgovarajući znakovi
u stringovima sve dok se ne naiđe na prvi par znakova koji su različiti. Usporedba je tada određena
odnosnom ta dva znaka, čiji je pak poredak fiksiran abecedom. Mala slova prethode velikim slovima, a velika slova prethode
brojevima. Ako je jedan string podstring drugog, onda je dulji string veći.
Pored operatora uspoređivanja string daje šest preopterećenih verzija funkcije compare
koja vrši leksikografsko uspoređivanje. Rezultat tih funkcija je analogan rezultatu koji daje funkcija
strcmp
iz standardne biblioteke jezika C. Dakle,
s1.compare (args);
daje sljedeći rezultat:
-
Pozitivnu vrijednost ako je
s1
veći od stringa kojeg reprezentiraargs
; -
Negativnu vrijednost ako je
s1
manji od stringa kojeg reprezentiraargs
; -
Nulu ako je
s1
jednak stringu kojeg reprezentiraargs
.
Funkcije su dane ovdje:
|
Uspoređuje |
|
Uspoređuje |
|
Uspoređuje |
|
Uspoređuje |
|
Uspoređuje |
|
Uspoređuje |