Nizovi karaktera – stringovi
Nizovi karaktera se u jeziku C interpretiraju na donekle poseban način. Naime,
stringovi u C-u se implementiraju kao null-terminated nizovi karaktera. Nullterminated
podrazumeva da se string u memoriji predstavlja kao niz karaktera koji se
završava posebnim karakterom “\0”. Ovaj karakter označava kraj stringa nevezano za
stvarno alocirani memorijski prostor niza. Na primer, posle deklarisanja promenjive:
char String1[15];
u memoriji će za ovu promenjivu biti rezervisano 15 bajtova, kao što je prikazano na
sledećoj slici:
Inicijalno, posle deklaracije promenjive, ne postoje garancije sta je sadržaj ovih
memorijskih lokacija. Deklarisanoj promenjivoj treba dodeliti vrednost, na primer,
sledećom naredbom:
Treba obratiti pažnju da je ovaj string dužine 11 karaktera (i blanko znak na se računa
kao karakter) i da u memorijskoj lokaciji zauzima bajtove redom od 0 do 10. Kao što
je već rečeno, string se završava specijalnim karakterom “\0” koji se u ovom slučaju
nalazi na lokaciji bajta 11. Znači, ako uračunamo i ovaj specijalni karakter u
promenjivu String1 se može smestiti string maksimalne dužine 14 karaktera
(uključujući i blanko znake). Jako je bitno znati da sistem ne vrši proveru veličine
stringa koji se upisuje i veličine rezervisanog memorijskog prostora. O tome
programer mora da vodi računa, da je deklarisani niz karaktera dovoljno veliki da
primi kompletan string koji mu se dodeljuje.
Praktični značaj specijalnog karaktera “\0” je da označi sistemu gde se završava
smisleni sadržaj stringa. Ovo je u skladu sa time da posle deklaracije ovaj niz
karaktera sadrži neke slučajne (besmislene) podatke. Tako, posle dodele rečenice
“Hello World” bajtovi na lokacijama 12, 13 i 14 će i dalje sadržati neke vrednosti koje
su tu sasvim slučajno. Sistem će kao string interpretirati (recimo štampati) karaktere
na pozicijama od 0 do 10. Dalje, moguće je da string sadrži specijalne karaktere “\0”
na više mesta. U tom slučaju će sistem kao string interpretirati karaktere na
pozicijama od 0 do p-1 pri čemu je p lokacija prvog pojavljivanja specijalnog
karaktera “\0” sa leve strane (počevši od pozicije 0).
Učitavanje i prikazivanje stringovnih podataka
U formatu za ulaz/izlaz koji se koristi u naredbama printf i scanf niz karaktera (string)
se označava specifikacijom konverzije “%s”. Na primer, ukoliko želimo da
odštampamo promenljivu String1 tipa string naredbom printf:
printf(“Uneti string je: %s”, String1);
na izlazu ćemo dobiti:
Uneti string je: Hello World
Specifikacija konverzije %s u formatu se zamenjuje konkretnim sadržajem
promenjive String1. %s se može naći na bilo kojoj poziciji formata (početku, kraju
ili negde u sredini) i jednostavno će biti zamenjen nizom karaktera koji sadrži
promenjiva koja je navedena kao drugi argument ove naredbe. U jednom formatu se
može odšampati i više promenjivih tipa string pri čemu treba voditi računa da će
svako pojavljivanje specifikacije konverzije zamenjije biti zamenjeno redom
promenjivama tipa string koje su navedene u pozivu funkcije printf. Na primer:
char rec1[] = “Jedan”;
char rec3[] = “tri.“;
printf(“%s dva %s“, rec1, rec2);
Ovaj niz naredbi će na izlazu odštampati:
Jedan dva tri.
Nešto je složenije korišćenje funkcije scanf. Ova funkcija kao prvi parametar uzima
standardan format string, kao i printf. Posle toga sledi niz pointera na promenjive koje
treba da prime unšene vrednosti. Ovde se postavlja pitanje šta je adresa niza karaktera
kada želimo da unesemo string. Iz prethodnog primera, sa rec1[0] pristupamo
prvom karakteru tog stringa. Možemo pisati:
char ch = rec1[0];
ili
rec1[0] = ‘j’;
Da bi dobili adresu prvog karaktera u stringu, što je ujedno i adresa stringa možemo
da kucamo
&rec1[0]
Međutim, u programskom jeziku C je naziv niza ujedno i pointer na prvi element tog
niza. Tako da je potpuno ekvivalentno da li pišemo rec1 ili &rec1[0]. Sada
konačno možemo da napišemo poziv funkcije scanf za učitavanje jednog stringa:
char mojeIme[13];
scanf(“%s“, mojeIme);
Standardno, u programskom jeziku C postoji određeni broj predefinisanih funkcija za
rad sa stringovima. Kako bi koristili ove funkcije potrebno je uključiti zaglavlje
string.h:
#include
Kopiranje stringova
Obzirom da su stringovi u stvari nizovi karaktera, za njihovo kopiranje postoji
posebna funkcija, tj. nije dovoljno napisati:
rec1 = rec2;
Ova naredba će imati najverovatnije neželjeni efekat. Obzirom da su rec1 i rec2 u
stvari pointeri na memorijske lokacije gde se nalaze stringovi efekat gornje naredbe je
da oba ova pokazivača pokazuju na istu memorijsku lokaciju i to onu na koju je
inicijalno pokazivao pointer rec2. Ne postoje dve odvojene kopije stringa. Dalje,
izmena promenjive rec1 ce izazvati i izmenu promenjive rec2 i obratno. Ovo
najčešće nije željeni rezultat. Kako bi izvršili kopiranje sadržaja stringa (u potpuno
nezavisnu kopiju) koristimo funkciju:
char *strcpy(char *dst, const char *src);
Efekat ove funkcije je da sadržaj stringa src kopira u string dst. Još jedan koristan
efekat je da ova funkcija takođe i vraća niz karaktera koji kopira.
Stringu koji je jednom deklarisan ali nije inicijalizovan se vrednost dodeljuje
ISKLJUČIVO korišćenjem ove funkcije. Dodela oblika:
char mojString[10];
mojString = “Elfak”;
je NEISPRAVNA.
Dužina stringa
Treba razlikovati dužinu stringa i veličinu rezervisanog memorijskog prostora za
smeštajne tog stringa. U opštem slučaju dužina stringa je manja od broja rezervisanih
bajtova. Manja je barem za jedan karakter i to je upravo “\0”, specijalni karakter
kojim se string završava. Dužina stringa je broj karaktera koji se nalaze pre
specijalnog karaktera “\0”. Funkcija koja se koristi u ovu svrhu je:
int strlen(const char *str);
Funkcija kao parametar uzima string čija se dužina traži, a vraća broj karaktera u
stringu kao integer vrednost.
Konkatenacija stringova
Vrlo čest je slučaj kada je potrebno nadovezati dva stringa. Ova operacija se naziva
konkatenacija. Na primer, konkatenacijom stringova “Jedan” i “ dva.” ćemo dobiti
string “Jedan dva.”. Ovo se postiže korišćenjem funkcije:
char *strcat(char *dst, const char *src);
Ova funkcija sadržaj stringa src nadovezuje na kraj stringa dst. Takođe, dobijeni
rezultat funkcija vraća kao niz karaktera.
Poređenje stringova
Ponekad je potrebno leksički uporediti dva stringa. Na primer, leksički string “Hello”
prethodi (manji je) stringu “World”, string “Helikopter” prethodi (manji je) stringu
“Hello”, a stringovi “World” i “World” su jednaki. Za ovo se koristi funkcija:
int strcmp(const char *first, const char *second);
Dva argumenta ove funkcije su stringovi koji se porede. Funkcija vraća integer
vrednost koja je manja od nule ukoliko prvi string prethodi drugom, pozitivnu integer
vrednost ukoliko drugi string prethodi prvom, a nulu ukoliko su dva stringa jednaka.
podrazumeva da se string u memoriji predstavlja kao niz karaktera koji se
završava posebnim karakterom “\0”. Ovaj karakter označava kraj stringa nevezano za
stvarno alocirani memorijski prostor niza. Na primer, posle deklarisanja promenjive:
char String1[15];
u memoriji će za ovu promenjivu biti rezervisano 15 bajtova, kao što je prikazano na
sledećoj slici:
String 1 -> |0| | | | | | | | | | | | | |14|
Inicijalno, posle deklaracije promenjive, ne postoje garancije sta je sadržaj ovih
memorijskih lokacija. Deklarisanoj promenjivoj treba dodeliti vrednost, na primer,
sledećom naredbom:
char String1[] = “Hello World”;
Posle izvršenja ove naredbe, sadržaj memorijskih lokacija će biti: |H|E|L|L|O| |W|O|R|L|D|\0| | | |
Treba obratiti pažnju da je ovaj string dužine 11 karaktera (i blanko znak na se računa
kao karakter) i da u memorijskoj lokaciji zauzima bajtove redom od 0 do 10. Kao što
je već rečeno, string se završava specijalnim karakterom “\0” koji se u ovom slučaju
nalazi na lokaciji bajta 11. Znači, ako uračunamo i ovaj specijalni karakter u
promenjivu String1 se može smestiti string maksimalne dužine 14 karaktera
(uključujući i blanko znake). Jako je bitno znati da sistem ne vrši proveru veličine
stringa koji se upisuje i veličine rezervisanog memorijskog prostora. O tome
programer mora da vodi računa, da je deklarisani niz karaktera dovoljno veliki da
primi kompletan string koji mu se dodeljuje.
Praktični značaj specijalnog karaktera “\0” je da označi sistemu gde se završava
smisleni sadržaj stringa. Ovo je u skladu sa time da posle deklaracije ovaj niz
karaktera sadrži neke slučajne (besmislene) podatke. Tako, posle dodele rečenice
“Hello World” bajtovi na lokacijama 12, 13 i 14 će i dalje sadržati neke vrednosti koje
su tu sasvim slučajno. Sistem će kao string interpretirati (recimo štampati) karaktere
na pozicijama od 0 do 10. Dalje, moguće je da string sadrži specijalne karaktere “\0”
na više mesta. U tom slučaju će sistem kao string interpretirati karaktere na
pozicijama od 0 do p-1 pri čemu je p lokacija prvog pojavljivanja specijalnog
karaktera “\0” sa leve strane (počevši od pozicije 0).
Učitavanje i prikazivanje stringovnih podataka
U formatu za ulaz/izlaz koji se koristi u naredbama printf i scanf niz karaktera (string)
se označava specifikacijom konverzije “%s”. Na primer, ukoliko želimo da
odštampamo promenljivu String1 tipa string naredbom printf:
printf(“Uneti string je: %s”, String1);
na izlazu ćemo dobiti:
Uneti string je: Hello World
Specifikacija konverzije %s u formatu se zamenjuje konkretnim sadržajem
promenjive String1. %s se može naći na bilo kojoj poziciji formata (početku, kraju
ili negde u sredini) i jednostavno će biti zamenjen nizom karaktera koji sadrži
promenjiva koja je navedena kao drugi argument ove naredbe. U jednom formatu se
može odšampati i više promenjivih tipa string pri čemu treba voditi računa da će
svako pojavljivanje specifikacije konverzije zamenjije biti zamenjeno redom
promenjivama tipa string koje su navedene u pozivu funkcije printf. Na primer:
char rec1[] = “Jedan”;
char rec3[] = “tri.“;
printf(“%s dva %s“, rec1, rec2);
Ovaj niz naredbi će na izlazu odštampati:
Jedan dva tri.
Nešto je složenije korišćenje funkcije scanf. Ova funkcija kao prvi parametar uzima
standardan format string, kao i printf. Posle toga sledi niz pointera na promenjive koje
treba da prime unšene vrednosti. Ovde se postavlja pitanje šta je adresa niza karaktera
kada želimo da unesemo string. Iz prethodnog primera, sa rec1[0] pristupamo
prvom karakteru tog stringa. Možemo pisati:
char ch = rec1[0];
ili
rec1[0] = ‘j’;
Da bi dobili adresu prvog karaktera u stringu, što je ujedno i adresa stringa možemo
da kucamo
&rec1[0]
Međutim, u programskom jeziku C je naziv niza ujedno i pointer na prvi element tog
niza. Tako da je potpuno ekvivalentno da li pišemo rec1 ili &rec1[0]. Sada
konačno možemo da napišemo poziv funkcije scanf za učitavanje jednog stringa:
char mojeIme[13];
scanf(“%s“, mojeIme);
Standardno, u programskom jeziku C postoji određeni broj predefinisanih funkcija za
rad sa stringovima. Kako bi koristili ove funkcije potrebno je uključiti zaglavlje
string.h:
#include
Kopiranje stringova
Obzirom da su stringovi u stvari nizovi karaktera, za njihovo kopiranje postoji
posebna funkcija, tj. nije dovoljno napisati:
rec1 = rec2;
Ova naredba će imati najverovatnije neželjeni efekat. Obzirom da su rec1 i rec2 u
stvari pointeri na memorijske lokacije gde se nalaze stringovi efekat gornje naredbe je
da oba ova pokazivača pokazuju na istu memorijsku lokaciju i to onu na koju je
inicijalno pokazivao pointer rec2. Ne postoje dve odvojene kopije stringa. Dalje,
izmena promenjive rec1 ce izazvati i izmenu promenjive rec2 i obratno. Ovo
najčešće nije željeni rezultat. Kako bi izvršili kopiranje sadržaja stringa (u potpuno
nezavisnu kopiju) koristimo funkciju:
char *strcpy(char *dst, const char *src);
Efekat ove funkcije je da sadržaj stringa src kopira u string dst. Još jedan koristan
efekat je da ova funkcija takođe i vraća niz karaktera koji kopira.
Stringu koji je jednom deklarisan ali nije inicijalizovan se vrednost dodeljuje
ISKLJUČIVO korišćenjem ove funkcije. Dodela oblika:
char mojString[10];
mojString = “Elfak”;
je NEISPRAVNA.
Dužina stringa
Treba razlikovati dužinu stringa i veličinu rezervisanog memorijskog prostora za
smeštajne tog stringa. U opštem slučaju dužina stringa je manja od broja rezervisanih
bajtova. Manja je barem za jedan karakter i to je upravo “\0”, specijalni karakter
kojim se string završava. Dužina stringa je broj karaktera koji se nalaze pre
specijalnog karaktera “\0”. Funkcija koja se koristi u ovu svrhu je:
int strlen(const char *str);
Funkcija kao parametar uzima string čija se dužina traži, a vraća broj karaktera u
stringu kao integer vrednost.
Konkatenacija stringova
Vrlo čest je slučaj kada je potrebno nadovezati dva stringa. Ova operacija se naziva
konkatenacija. Na primer, konkatenacijom stringova “Jedan” i “ dva.” ćemo dobiti
string “Jedan dva.”. Ovo se postiže korišćenjem funkcije:
char *strcat(char *dst, const char *src);
Ova funkcija sadržaj stringa src nadovezuje na kraj stringa dst. Takođe, dobijeni
rezultat funkcija vraća kao niz karaktera.
Poređenje stringova
Ponekad je potrebno leksički uporediti dva stringa. Na primer, leksički string “Hello”
prethodi (manji je) stringu “World”, string “Helikopter” prethodi (manji je) stringu
“Hello”, a stringovi “World” i “World” su jednaki. Za ovo se koristi funkcija:
int strcmp(const char *first, const char *second);
Dva argumenta ove funkcije su stringovi koji se porede. Funkcija vraća integer
vrednost koja je manja od nule ukoliko prvi string prethodi drugom, pozitivnu integer
vrednost ukoliko drugi string prethodi prvom, a nulu ukoliko su dva stringa jednaka.
0 Comments:
Post a Comment
<< Home