Sztringek
Sztringek¶
A program futása során a felhasználóval való kommunikáció általában a program által kiírt, illetve a felhasználó által bevitt szövegeken, karaktersorozatokon keresztül történik.
Az ilyen karaktersorozatok tárolására kézenfekvő megoldást jelent a karakter tömb típus, amely segítségével tetszőleges hosszú szöveget, sztringet tudunk megadni.
A megvalósítás során a sztring mérete azért nem lehet teljesen tetszőleges, valamilyen korlátot kell adni a méretre, mint minden egyéb tömb méretre, hiszen a program memóriája is véges.
Így általában Sztring(n)
típusú sztringekről beszélhetünk, amiket E
= karakter alaptípusból és I
= {0, \(\dots\), n-1} indextípusból képzett tömbökkel reprezentálhatunk, és amiknek az értékkészlete a legfeljebb n
hosszúságú karaktersorozatok halmaza.
A sztringnek, mint virtuális adattípusnak a műveletei lehetnek egy konkrét karakter kiolvasása, karakter módosítása, hosszának meghatározása, egyik sztring értékadása a másiknak, két sztring összefűzése, vagy esetleg összehasonlítása.
A különböző n
méretekkel implementált sztringek nagymértékben kompatibilisek egymással, műveleteik megegyeznek, és az értéktartományokon belül azonos eredményt adnak.
Nem meglepő módon karaktersorozatot egyszerűen egy karakteres tömbbel készítünk. Például:
1 |
|
Ezen deklaráció során h
bájt foglalódik, amelyen h-1
hosszú karakter sorozat tárolható.
Ez persze csak felső korlátot ad a sztring hosszára, rövidebb sztring is tárolható ebben a tömbben.
Ami a sztringeket egyedivé teszi a tömbök között az az, hogy minden sztring lezárására egy '\0'
karakter kerül a sztring végére.
Emiatt van az, hogy a fenti h
méretű karaktertömbben legfeljebb csak h-1
hosszú sztring tárolható el: egy helyet mindig fent kell tartani a lezáró '\0'
karakterre.
Ezzel a megoldással érjük el azt, hogy adott méretnél rövidebb sztring is könnyen eltárolható legyen.
Sztring mérete és hossza
A C nyelvben a sztringeknél élesen meg kell tudni különböztetni a sztring méretét és hosszát. A méretet a sztring létrehozásakor, deklarációjakor adjuk meg, ez egy fix, adott változóra nézve konstans érték. A hosszt a sztring aktuális értéke adja meg, ez egy adott változóra nézve a futás során változó (változtatható) érték.
Legyen char str[6];
egy sztring deklarációja, ekkor az "egy", "alma" és "meggy" szavak, valamint az üres sztring ("") az alábbi módon tárolódnak el:
Az str
sztring i
. karakterére str[i-1]
-ként hivatkozhatunk.
Ne feledjük, hogy a sztring egy speciális tömb, a tömbök indexelése pedig 0-tól kezdődik!
Amikor deklarálunk egy szringet, akkor megtehetjük, hogy egyből inicializáljuk is. Lévén minden sztring egy karaktertömb, így karaktertömbként inicializálhatjuk. Például:
1 |
|
Ez persze felettébb hosszadalmas és kényelmetlen leírni a sok aposztróf miatt, ezért a karaktertömböket inicializálhatjuk sztring literálok segítségével is, amelyeket idézőjelek között adunk meg. Például:
1 |
|
A sztring literálban a legtöbb, a karakter literáloknál már megismert escape szekvencia használható.
Az egyetlen különbség a határolójelekből adódik: míg karakter esetén az aposztrófot kell escape szekvenciával megadni ('\''
, '"'
), addig sztringek esetében az idézőjelet ("'"
, "\""
).
Egymástól csak whitespace karakterekkel (szóköz, tabulátor,..) elválasztott sztring literálokat a fordító összefűzi, és egyetlen értékként kezeli:
1 2 3 4 5 |
|
A sztring műveletei¶
A sztring adott karakterének kiolvasása, illetve módosítása, mint műveletek adottak az által, hogy a sztring egy speciális tömb. Azonban kihasználva azt, hogy ebben a tömbben változó hosszúságú sztringeket tárolhatunk, ráadásul a sztring végét jelzi egy speciális karakter, definiálhatjuk azt a műveletet is, ami adott sztring tényleges hosszát adja vissza.
A teljesség igénye nélkül nézzünk erre egy konkrét megvalósítást:
1 2 3 4 5 |
|
A függvény paraméterében kapja a tömböt, ami tartalmazza a sztringet, aminek a hosszát meg kell határozni.
Egy for
utasítás ciklusváltozójával végigfutunk a sztringen, és vizsgáljuk, hogy elértük-e a lezáró speciális karaktert.
Ha igen, a ciklus végére értünk.
Érdekes megfigyelni a ciklust alaposabban is: maga a ciklus magja egy üres utasítás, a lényeg azon van, hogy mindig növeljük a ciklusváltozót, amely végül megadja a sztring méretét.
Mivel a sztring egy elég gyakran használt adattípus, így nem véletlen, hogy a könnyebb használhatóság érdekében a függvénykönyvtár számos olyan függvényt tartalmaz, amely ezek kezelését, feldolgozását segíti.
Ahhoz, hogy ezeket használni tudjuk, include-olnunk kell a string.h
header állományt.
Az ebben elérhető függvényekből szemezget az alábbi táblázat:
Függvény | Leírás |
---|---|
size_t strlen(const char *s) |
Egy sztring hosszának meghatározása. |
int strcmp(const char *s1, const char *s2) |
Két sztring összehasonlítása lexikografikus rendezéssel. |
int strncmp(const char *s1, const char *s2, size_t n) |
Két sztring összehasonlítása lexikografikus rendezéssel legfeljebb n karakterhosszon. |
char *strdup(const char *src) |
A sztring duplikálása új sztring létrehozásával. |
char *strndup(const char *src, size_t n) |
A sztring duplikálása új sztring létrehozásával legfeljebb n karakterhosszon. |
char *strcpy(char *dest, const char *src) |
Egy sztring értékének másolása megadott helyre. |
char *strncpy(char *dest, const char *src, size_t n) |
Egy sztring értékének másolása megadott helyre legfeljebb n karakterhosszon. |
char *strcat(char *dest, const char *src) |
Egy sztring hozzáfuzése egy másik sztringhez. |
char *strncat(char *dest, const char *src, size_t n) |
Egy sztring hozzáfuzése egy másik sztringhez legfeljebb n karakterhosszon. |
size_t strnlen_s(const char *s, size_t sz) |
Egy sztring hosszának meghatározása a \(C^{11}\) szabványtól kezdve. |
errno_t strncpy_s(char *dest, rsize_t sz, const char *src, rsize_t n) |
Egy sztring értékének biztonságosabb másolása megadott helyre a \(C^{11}\) szabványtól kezdve. |
errno_t strncat_s(char *dest, rsize_t sz, const char *src, rsize_t n) |
Egy sztring biztonságos hozzáfuzése egy másik sztringhez a \(C^{11}\) szabványtól kezdve. |
Info
Ha további műveleteket szeretnénk megismerni, amikkel a sztringek kezelése egyszerűbb lehet, érdemes a string.h
műveletei között szétnézni.
A parancsokról részletesebb leírást linux alatt a man
parancs használatával kaphatunk szükség esetén.
A sztring műveleteknek nagyon kell vigyáznia arra, hogy a kezelni kívánt sztring az valóban "megfelelő" formátumú-e. Azaz megvan-e a sztringet lezáró karakter, illetve a sztring mutató nem üres sztringre mutat-e. Sokszor ezek hiánya a program működésében nem várt hibákat okozhatnak, ha nem figyelünk rá.