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
char str[h];

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:

kep

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
char str = {'s','z','t','r','i','n','g','\0'};

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
char str = "sztring";

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
"Helló Világ!\n"
"Hány forintot váltsunk?"
"%lf"
"%lf HUF = %lf EUR\n"
"Egybe" "írva és külön is," " ez egyetlen sztring lesz."

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
int strlen(char s[]) {
    int i;
    for (i = 0; s[i] != '\0'; ++i);
    return i;
}

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á.


Utolsó frissítés: 2020-10-21 18:18:34