You are on page 1of 10

NIZOVI ZNAKOVA (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;

cout << ch;


ch = \t;
cout << ch
ch = \\;
cout << ch;
}

return 0;

NIZOVI ZNAKOVA (STRING)


U programskim jezicima C i C++ ne postoji posebno ugraeni tip za nizove znakova. Umjesto
toga, u tu svrhu se koristi polje iji su elementi tipa char. U svaki element polja se pohranjuje
jedan znak rijei ili reenice koja je predstavljena tim poljem. Najosnovnija upotreba
(uitavanje i ispisivanje) se izvodi na isti nain kao i kod drugih osnovnih tipova, dok se ostale
osnovne operacije (pridruivanje, usporedba te spajanje dva niza znakova) izvode na malo
drugaiji nain.

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.

PRIKAZ NIZA ZNAKOVA U MEMORIJI


Pretpostavimo da je korisnik prethodnog programa unio rije Ivo. Naredba ispisa bi tada
trebala ispisati tu rije na zaslon. Meutim, postavlja se pitanje, kako e naredba ispisa znati
da treba ispisati samo prva tri uitana znaka? Razlog tome je to se u polje sprema posebni
znak koji oznaava koji dio polja zapravo predstavlja rije. Oito je naime da u prethodnom
primjeru ne moraju se rijei biti maksimalne duine. Taj poseban znak se zove null

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.

KONSTANTE NIZA ZNAKOVA (STRING KONSTANTE)


String konstante su ve esto upotrebljavane. U programu se navode tako da se podatak
(rije ili reenica) stavi unutar dvostrukih navodnika. Npr.
Ivo

Mama ide u duan

su primjeri string konstanti. Vano je razlikovati string konstante od znakovnih konstanti.


Znakovna konstanta predstavlja jedan znak, dok string konstanta predstavlja jedan ili vie
znakova nakon kojih se nalazi null terminator. Drugim rijeima konstante A i A su razliite.
Prva predstavlja niz od jednog znaka (prevodilac skriveno dodaje null terminator), dok druga
predstavlja jedan znak.

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

Da bi se funkcija strcpy (i sline funkcije opisane u nastavku) mogla upotrebljavati potrebno je


ukljuiti na poetku programa datoteku STRING.H. Slijedei primjer je prikazuje cjeloviti
program koji se moe prevesti:
#include <iostream.h>
#include <string.h>

// potrebno zbog upotrebe strcpy

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;
}

USPOREDBA DVA STRINGA


Usporeivanje dva stringa se obavlja pozivom funkcije strcmp ili stricmp. Prva funkcija
razlikuje velika i mala slova, dok druga funkcija ne pravi tu razliku. Obje funkcije imaju istu
sintaksu poziva. Funkcije primaju dva argumenta dva niza koja se meusobno usporeuju.
Funkcije kao rezultat vraaju cijeli broj koji se tumai na slijedei nain:
rezultat funkcije
0
broj vei od nule
broj manji od nule

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

(tj. strcmp(Iva,Ana) je vee od nule)


(tj. strcmp(Iva,Maja) je manje od nule)
(tj. strcmp(Iva,Ivana) je manje od nule)

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

= strcmp(unos,XXX); // usporedi stringove


== 0)
// ako su stringovi identini
<< Nastavak!\n;
<< Kraj!\n;

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.

UITAVANJE VIE OD JEDNE RIJEI U STRING


Uitavanje stringa sa tipkovnice upotrebom cin objekta (i operatora <<) ima jedan veliki
nedostatak, a to je da se u varijablu zapisuje samo prva rije. este su situacije kada je
potrebno uitati vie od jedne rijei u string (npr. naslov ili cijelu reenicu). Taj problem se
moe jednostavno rijeiti na dva naina.

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;

ANALIZA ZNAKOVA U STRINGU


Dosadanji primjeri pokazali su kako je mogue izvesti tipine operacije nad stringovima
upotrebom postojeih funkcija. U praksi je ponekad potrebno napraviti odreene operacije
nad stringom koje nisu posebno podrane odgovarajuom funkcijom. Tada se radi slino kao i
sa poljima. Potrebno je napraviti for petlju koja prolazi kroz string znak po znak i operaciju
izvesti nad svakim znakom posebno. Prije pisanja petlje koja prolazi kroz cijeli string,
potrebno je upoznati funkciju strlen koja vraa duinu stringa (tj. broj znakova u stringu).
Funkcija strlen prima jedan argument, naziv stringa, a vraa broj znakova u tom stringu (tj.
broj znakova koji se nalaze prije null terminatora). Za upotrebu funkcije potrebno je takoer
ukljuiti datoteku STRING.H. Openito, petlja koja prolazi kroz sve znakove u stringu moe se
napisati na slijedei nain:
char string[100];
// ovdje je potrebno ucitati string
int n = strlen(string); // broj ucitanih znakova
for (int i = 0;i < n;i++) // za svaki znak u stringu
// obaviti operaciju nad znakom string[i]

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;
}

Upotreba u main funkciji se moe napraviti na slijedei nain:


char unos[100];
cin >> unos;
cout << broj_pojave(unos,a); // koliko puta se u stringu
// javlja malo slovo a
Ovako definirana funkcija moe primati samo string varijablu. Ako elimo da funkcija moe
primati i string konstantu (tj, niz znakova unutar navodnika), tada je potrebno pri deklaraciji
funkcije odgovarajui argument deklarirati tako da bude tipa const char * umjesto char *.
Konkretno na prethodnom primjeru se mijenja samo deklaracija funkcije:
int broj_pojave(const char *string, char znak)
Sada je u main funkciji mogue funkciju upotrijebiti i na ovaj nain:
cout << broj_pojave(Mama,a);
Openito, ako funkcija eli promijeniti original, tada se rije const isputa pri deklaraciji
argumenta. Meutim, tada se pri pozivu funkcije mora navesti naziv varijable. S druge strane,
ako funkcija ne mijenja argument, tada ga je pametno deklarirati sa modifikatorom const
ispred, jer je onda mogue poslati i string konstantu. Slijedea funkcija prima kao argument tri
stringa te u prvi string upisuje spojene drugi i trei. Oito je da prvi string mora biti deklariran
bez const modifikatora, dok je poeljno da druga dva stringa imaju const modifikator.
void spoji(char *dest, const char *s1, const char *s2)
{
strcpy(dest, s1); // dest = s1
strcat(dest, s2); // dodaj na kraj stringa dest string s2
}
U main funkciji mogue je funkciju spoji upotrijebiti na slijedei nain:
char izlaz[20];
spoji(izlaz,Ivo ,Ivic);
cout << izlaz << endl;

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);
};

char *Radnik::get_ime() const


{
return ime;
}
void Radnik::set_ime(const char *novo_ime)
{
strcpy(ime,novo_ime);
}
main()
{
Radnik Ivo;
char unos[20];
cout << Unesite ime radnika: ;
cin >> unos;
// poziv set metode
Ivo.set_ime(unos);
// poziv get metode
char ime[20];
strcpy(ime,Ivo.get_ime());
cout << Ime radnika: << ime << endl;
return 0;
}
U ovom primjeru se u klasi nalazi jedan string podatkovni lan te klasine set i get metode.
Bitno je uoiti da metoda get_ime vraa pokaziva na tip char. Naime, vano je podsjetiti da
je string zapravo polje znakova, a polje je isto to i pokaziva. Iz istih razloga, metoda
set_ime prima novu vrijednost koja se sprema u podatkovni lan ime u obliku pokazivaa na
tip char. U glavnoj funkciji, povratna vrijednost metode get_ime se koristi kao drugi argument
funkcije strcpy. Budui da je drugi argument funkcije strcpy zapravo izvorini string, time se
postie da se sadraj lana ime objekta Ivo iskopira u lokalnu varijablu ime funkcije main.

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.

You might also like