Professional Documents
Culture Documents
4 2 Stringovi
4 2 Stringovi
Nizovi znakova (ili stringovi) slue za predstavljanje znakovnih podataka kao to su npr. rijei
ili reenice u memoriji. U programskom jeziku C i C++, osnova za predstavljanje nizova
znakova je znakovni tip char. Nizovi znakova se predstavljaju upotrebom polja sa char
elementima.
ZNAKOVNI TIP
Znakovni tip char slui za pohranjivanje jednog znaka u radnu memoriju. Pod znakom se
najee podrazumijevaju slova i brojevi, iako postoje i razni drugi znakovi. Znakovne
varijable mogu se upotrebljavati na gotovo isti nain kao i druge varijable osnovnog tipa:
main()
{
char unos;
cout << Unesite jedan znak: ;
cin >> unos;
cout << Unijeli ste: << unos << endl;
}
return 0;
Znakovne konstante se piu tako da se konkretan znak (samo jedan) navede unutar
jednostrukih navodnika. Slijedei primjer ilustrira tipini nain upotrebe:
main()
{
char ch;
cout << Unesite N za nastavak: ;
cin >> ch;
if (ch == N)
cout << Nastavak\n;
else
cout << Kraj!\n;
return 0;
Vano je napomenuti da postoji razlika izmeu velikih i malih slova. U prethodnom primjeru,
program e nastaviti s radom (tj. ispisati e se poruka Nastavak) samo ukoliko korisnik
unese veliko slovo N. Ukoliko ne elimo da na program pravi razliku izmeu velikih i malih
slova, to moemo jednostavno napraviti u if uvjetu:
if (ch == N || ch == n)
cout << Nastavak\n;
ASCII TABLICA
U osnovi, raunalo ne prepoznaje znakove. Svi podaci zapisani u raunalu su zapisani u
obliku brojeva. Ovo takoer vrijedi i za znakovni tip. Naelno, znakovi su prikazani u raunalu
tako da je svakom znaku pridruen jedinstveni broj. Kada se ispisuje znak (recimo na zaslon),
raunalo zna o kojem znaku je rije pomou njegovog broja. Tablica koja odreuje kojim
znakovima su pridrueni brojevi, zove se ASCII tablica. Odgovarajui broj za neki znak se
zove ASCII kod. ASCII tablica sadri 256 znakova (brojevi tj. ASCII kodovi se kreu od 0 do
255). Tako npr. veliko slovo A (tj. znak A) ima ASCII kod 65. Znakovnim varijablama moe se
pridruiti brojana vrijednost. Time se zapravo u varijablu sprema znak sa odgovarajuim
ASCII kodom. Ovo je ilustrirano slijedeim naredbama:
char ch;
ch = 65; // isto kao i ch = A
cout << ch << endl; // ispis
cin >> ch;
if (ch == 65) // isto kao i if (ch == A)
cout << Unijeli ste znak A\n;
Vano je napomenuti da brojevni znakovi nemaju iste ASCII kodove kao i brojevi koje
predstavljaju. Npr. znak 0 nema ASCII kod 0. Ukoliko elimo ispitati je li korisnik unio
odreeni brojevni znak (ne broj), to moemo napraviti na slijedei nain:
main()
{
char ch;
while (1)
{
cout << 1. Unos\n;
cout << 2. Ispis\n;
cout << X. Izlaz\n;
cin >> ch;
if (ch == 1) // a ne if (ch == 1)
// unos
else if (ch == 2)
// ispis
else if (ch == X || ch == x)
return 0;
else
cout << Pogrean odabir!\n;
}
Gornji program prikazuje kostur izbornika, gdje korisnik pri odabiru opcije moe unijeti broj ili
znak. Stoga se za uitavanje upotrebljava znakovna varijabla. Vano je primjetiti da se pri
ispitivanju je li korisnik unio broj 1 ili 2, broj stavlja unutar jednostrukih navodnika. Da je
varijabla ch bila tipa int, jednostruke navodnike bi trebalo ispustiti.
POSEBNI ZNAKOVI
Posebni znakovi slue za prikaz znakova koji se ne mogu jednostavno staviti unutar
jednostrukih navodnika. Najee upotrebljavani su newline (prelazak u novi red), te
tabulator. Znak newline se u programu prikazuje kao \n, dok se tabulator prikazuje kao \t.
Openito, svi posebni znakovi zapoinju sa znakom \. Zbog toga je i za znak \ potreban
posebni prikaz: \\. Slijedei primjer prikazuje osnovnu upotrebu:
main()
{
char ch;
ch = \n;
return 0;
OSNOVNA UPOTREBA
DEKLARACIJA, UITAVANJE I ISPIS
Slijedei primjer prikazuje najosnovniju upotrebu niza znakova:
main()
{
char niz[20]; // niz znakova
cout << Unesite jednu rijec: ;
cin >> niz; // ucitavanje
cout << niz << endl; // ispis
return 0;
}
U prvoj liniji funkcije main, deklariran je niz znakova. Odgovarajua varijabla u ovom primjeru
zove se niz, a deklarirana je kao polje od dvadeset elemenata tipa char. Vana injenica je da
se u ovako deklarirano polje se moe smjestiti niz od najvie 19 znakova (uzrok e biti
objanjen neto kasnije). Pri uitavanju i ispisivanju niza znakova se navodi samo naziv polja
(bez uglatih zagrada). Za obina polja uitavanje i ispis pomou cin i cout nije podrano, no
za polje znakova je to posebno podrano. Kao posljedica uitavanja, rije koju korisnik upie
se sprema u polje niz. Ista stvar vrijedi i za ispis, te e se tako niz znakova ispisati na zaslon.
terminator i oznaava kraj stringa. Drugim rijeima, naredba ispisa e ispisati sve znakove u
polju koji se nalaze prije null terminatora. Znakovna oznaka za null terminator je \0. Slijedea
slika ilustrira kako je u prethodnom primjeru popunjeno polje kada korisnik unese rije Ivo:
I
\0
Prvi znak (tj. prvo slovo uitane rijei) se nalazi na nultoj poziciji u polju, slijedei znak je na
prvoj poziciji itd. Odmah nakon svih uitanih znakova slijedi znak \0 koji oznaava kraj
stringa. Sve operacije koje na neki nain analiziraju niz znakova (npr. naredba ispisa,
usporedba, pridruivanje i sl.) uzet e u obzir samo one znakove koji se nalaze prije \0
znaka. Iz tog razloga u prethodnom primjeru se smije unijeti rije od najvie 19 znakova.
Naime, u prethodno polje mogue je spremiti najvie 20 podataka tipa char. Svaki niz
znakova mora zavravati sa \0 te je jedno mjesto unaprijed rezervirano. Preostaje jo 19
slobodnih mjesta za znakove od kojih se sastoji sam podatak (rije, reenica). Openito
reeno ako je niz znakova deklariran na slijedei nain:
char niz[MAX];
tada se u taj niz moe pohraniti najvie MAX 1 znakova.
PRIDRUIVANJE
Ve je ranije spomenuto da su jedine operacije nad stringovima posebno podrane u C i C++
jezicima uitavanje i ispis. Drugim rijeima, slijedee naredbe nisu doputene:
char niz1[10], niz2[10];
niz1 = Ivo; // nije doputeno
niz2 = niz1; // nije doputeno
Pridruivanje nizova znakova izvodi se pomou funkcije strcpy (naziv je skraen od string
copy). Funkcija prima dva argumenta. Prvi argument je odredini niz znakova (varijabla u koju
se sprema podatak), dok je drugi podatak izvorini niz znakova (tj. sadraj koji se sprema).
Drugi podatak moe biti neko drugo polje znakova, ali moe biti i string konstanta. Prethodna
pridruivanja se mogu izvesti pomou slijedeih naredbi:
char niz1[10], niz2[10];
strcpy(niz1, Ivo); // niz1 = Ivo
strcpy(niz2, niz1); // niz2 = niz1
main()
{
char niz[20];
strcpy(niz,Dobar dan!); // pridruivanje
cout << niz;
}
return 0;
SPAJANJE STRINGOVA
Pod spajanjem stringova misli se na pridruivanje jednog stringa na kraj drugog. Spajanje se
obavlja pozivom funkcije strcat za iju upotrebu je takoer potrebno ukljuiti datoteku
STRING.H. Funkcija prima dva argumenta. Slino kao i kod strcpy funkcije, prvi argument je
odredite, dok je drugi izvorite. Razlika je u tome to se izvorini string pridodaje na kraj
odredinog stringa. Nakon Slijedeeg niz naredbi u stringu niz e se nai sadraj IvoIvic.
char niz[20];
strcpy(niz,Ivo); // pridruivanje
strcat(niz,Ivic); // spajanje
Ovaj primjer ilustrira i jednu bitnu karakteristiku funkcije strcpy. Izvorini niz se pridodaje
neposredno na kraj odredinog. Ukoliko pri spajanju elimo da se ubaci i npr. znak razmaka,
moramo to runo napraviti. Slijedei primjer uitava odvojeno ime i prezime i zatim i spaja u
jedinstveni itljiv niz znakova:
#include <iostream.h>
#include <string.h>
main()
{
char ime[10],prezime[10];
cout << Unesite ime: ;
cin >> ime;
cout << Unesite prezime: ;
cin >> prezime;
char puno_ime[20];
strcpy(puno_ime, ime);
// pridruzi ime u puno_ime
strcat(puno_ime, );
// dodaj razmak na kraj
strcat(puno_ime, prezime); // dodaj prezime na kraj
cout << puno_ime << endl;
return 0;
}
znaenje rezultata
stringovi su identini
prvi string je vei od drugog
prvi string je manji od drugog
Kada se kae da je prvi string vei od nekog drugog, moe se rei da po abecedi (engleskoj),
prvi string dolazi poslije drugog. Slino, prvi string je manji od drugog ukoliko po abecedi
dolazi prije drugog stringa. Tako npr. vrijede slijedei odnosi:
Iva > Ana
Iva < Maja
Iva < Ivana
Pojmovi prvi i drugi string, se odnose na prvi tj. drugi argument funkcije strcmp ili stricmp.
Slijedei primjer prikazuje osnovnu upotrebu:
#include <iostream.h>
#include <string.h>
main()
{
char unos[20];
cout << Unesite XXX za nastavak: ;
cin >> unos;
int rez
if (rez
cout
else
cout
return 0;
}
U ovom programu, korisnik mora unijeti XXX za nastavak. Usporedba se obavlja pozivom
funkcije strcmp te se zapisuje u varijablu rez. Ukoliko su dva stringa isti (tj. korisnik je unio
XXX), tada e rezultat usporedbe biti nula. U suprotnom e rezultat biti razliit od nule. Vano
je primjetiti da pri unosu sva tri slova X moraju biti velika slova. Ukoliko se korisniku eli
omoguiti da ne mora paziti na raspored velikih/malih slova, tada je potrebno pozvati funkciju
stricmp umjesto funkcije strcmp. U tom sluaju e rezultat usporedbe biti 0 (smatrati e se da
je korisnik unio tri slova X) uvijek kada se unesu tri slova X bez obzira na to je li koje od
unesenih slova veliko ili malo.
Prvi nain je upotrebom get metode cin objekta. Ta metoda prima dva argumenta, pri emu je
prvi argument niz znakova u koji se uitava, dok je drugi argument maksimalni broj znakova
koji e se spremiti u niz (umanjen za jedan). Slijedei primjer ilustrira primjenu get metode cin
objekta:
#include <iostream.h>
main()
{
char niz[100];
cout << Unesite recenicu: ;
cin.get(niz,100);
cout << niz << endl;
}
return 0;
U varijablu niz e se spremiti svi znakovi koji se unesu do pritiska na tipku enter. Ukoliko
korisnik programa unese vie od 99 znakova, u stringu e se nai samo prvih 99 znakova.
Slino je mogue napraviti i pozivom funkcije gets, koja prima samo jedan argument: naziv
stringa. Za upotrebu te funkcije potrebno je ukljuiti datoteku STDIO.H. Slijedei primjer
pokazuje upotrebu ove funkcije:
#include <stdio.h>
#include <iostream.h>
main()
{
char niz[100];
cout << Unesite recenicu: ;
gets(niz);
cout << niz << endl;
}
return 0;
Ova petlja funkcionira kao i svaka tipina petlja koja prolazi kroz sve elemente polja. Potrebno
je samo imati na umu da je jedan element stringa zapravo varijabla tipa char (tj. element
stringa je jedan znak). Slijedei program trai od korisnika da unese jednu reenicu te broji
koliko rijei postoji u toj reenici. To radi tako da broji koliko puta u reenici se pojavljuje znak
(tj. razmak):
#include <iostream.h>
#include <string.h>
#include <stdio.h>
main()
{
char rec[100];
cout << Unesite recenicu: ;
gets(rec);
int br_raz = 0; // broj razmaka
int n = strlen(rec);
for (int i = 0;i < n;i++) // za sve znakove
if (rec[i] == )
// ako je znak razmak
br_raz++;
cout << Broj rijeci iznosi: << br_raz << endl;
}
return 0;
STRINGOVI I FUNKCIJE
Vano je cijelo vrijeme imati na umu da je string zapravo polje iji su elementi tipa char.
Stoga, kada funkcija prima string argument, isto kao i kod obinih polja, funkcija prima
pokaziva na tip char. Sama funkcija se ne mora brinuti oko toga to je rije o pokazivau,
nego ka jednostavno koristi kao da je rije o klasinom stringu (to je zapravo i istina). Za
razliku od dosadanjih funkcija koje su primale polje kao argument, nije potrebno posebno
poslati broj elemenata u polju. Naime to se moe pribaviti funkcijom strlen. Funkcija strlen
zna koliko je znakova u stringu jednostavno zato to ona zna da string zavrava sa
znakom \0.
Slijedea funkcija broji koliko puta se odreeni znak javlja u nekom stringu:
int broj_pojave(char *string, char znak)
{
int rez = 0;
int n = strlen(string);
for (int i = 0;i < n;i++)
if (string[i] == znak) // ako je i-ti znak jednak
// trazenom znaku
rez++;
return rez;
}
STRINGOVI U KLASI
String varijabla moe biti lan klase (tj. pripadnog objekta). Tipine operacije, kao to su
pristupne metode (set i get), se izvode na slian nain kao i kod prijanjih tipova varijabli. U
slijedeem primjeru dana je klasa radnik koja posjeduje jedan string lan ime radnika:
#include <iostream.h>
#include <string.h>
class Radnik
{
private:
char ime[20];
public:
char *get_ime() const;
void set_ime(const char *novo_ime);
};
POLJE STRINGOVA
Budui da je string zapravo polje sa elementima tipa char, tada je polje stringova zapravo
dvodimenzionalna matrica u kojoj su elementi tipa char. Openito, polje stringova se moe
deklarirati na slijedei nain:
char strings[MAX][LEN];
Pri emu je MAX cjelobrojna konstanta koju treba ranije definirati (ili umjesto nje navesti neki
broj). Ta konstanta oznaava koliko stringova se nalazi u polju. Slino vrijedi i za konstantu
LEN koja oznaava najvei broj znakova (uvean za jedan zbog \0 znaka) koji se moe
spremiti u jedan string u takvom polju. Npr.
char imena[50][20];
Ovom deklaracijom se deklarira polje stringova u koje je mogue spremiti najvie 20
stringova. U svaki string stane najvie 19 znakova.
Pristup elementima se odvija slino kao i kod obinih polja. Drugim rijeima, ako se unutar
programa navede imena[5] time se zapravo misli na 6. string u polju. Ako se pak navede
imena[5][0], to oznaava 1. znak u 6. stringu polja stringova.