Ablakok.  Vírusok.  Jegyzetfüzetek.  Internet.  hivatal.  Segédprogramok.  Drivers

#beleértve char *strtok(char * str1, const char * str2);

Az strtok() függvény egy mutatót ad vissza a paraméter által mutatott karakterlánc következő tokenjére. str1. A paraméter által megcímzett karakterláncot alkotó karakterek str2, olyan határolók, amelyek egy tokent határoznak meg. Ha nincs visszaadandó token, nulla mutató kerül visszaadásra.

A C99-es verzióban a paraméterek str1És str2 az alkalmazott korlátozási minősítő.

Egy karakterlánc tokenekre való felosztásához az strtok() függvény első meghívásakor a paraméter str1 ennek a sornak az elejére kell mutatnia. A következő függvényhívásoknál paraméterként str1 null mutatót kell használni. Ily módon a teljes karakterlánc tokenizálódik.

Az strtok() függvény minden hívása más-más elválasztó készletet használhat.

Példa

Ez a program a "Zöld a fű, süt a nap" karakterláncot szóközzel és vesszővel elválasztott jelzőkre bontja. Az eredmény az lesz

Fű|Zöld|Napfény|Ragyog #beleértve #beleértve int main(void) ( char *p; p = strtok("A fű zöld, süt a nap", " "); printf(p); do ( p = strtok("\0", ", ") ; if(p ) printf("|%s", p); ) while(p); return 0; )

A programozási nyelvek tartalmazhatnak speciális funkciók stringekkel dolgozni, ezzel megkímélve a programozót attól, hogy saját karakterlánc-feldolgozó függvényeket kelljen írnia. Például gyakran meg kell határozni egy karakterlánc hosszát, így a nyelvek funkciót biztosítanak a hosszának mérésére.

A C programozási nyelvben a karakterláncokkal való munkavégzés függvényei a string.h fejlécfájlban vannak deklarálva, amelyeket feltétlenül szerepeltetni kell a forráskódban. Körülbelül húsz függvény létezik a karakterláncokkal való munkához. Köztük vannak olyanok, amelyek karaktereket keresnek egy karakterláncban, összehasonlító függvények, karakterlánc-másolás, valamint konkrétabbak is. A legtöbb létező listája és leírása Ebben a pillanatban a C nyelvben a függvények megtalálhatók B. Kernighan, D. Ritchie "A C programozási nyelv. Második kiadás" című könyvének függelékében.

A string.h-ban deklarált összes függvény módosíthatja vagy nem módosíthatja a mutató által átadott karakterláncokat a munkája során. Ez a funkció céljától függ. A legtöbb azonban visszaad valamit: vagy egy karakterre mutató mutatót, vagy egy egész számot. Sőt, ha a függvény megváltoztatja az egyik paraméterét, és erre hívták, akkor amit visszaad, az figyelmen kívül hagyható (vagyis nem rendelhető semmihez a hívó függvényben).

Például az strcpy() függvénynek a következő deklarációja van: char *strcpy (char *, const char*) . A második paraméter által mutatott karakterláncot átmásolja az első paraméter által mutatott karakterláncba. Tehát az első paraméter megváltozik. Ezenkívül a függvény egy mutatót ad vissza a karakterlánc első karakterére:

char s1[10], s2[10]; char*s3; s3 = s2; kap (s1) ; s3 = strcpy (s2, s1) ; tesz (s2) ; tesz (s3) ; printf("%p, %p \n", s2, s3) ;

Itt s2 és s3 ugyanarra a karakterre mutat (a printf() ugyanazt a címet adja ki). Azonban amit az strcpy() ad vissza, azt nem lehet tömbhöz rendelni. Ennek a függvénynek az eredménye általában nincs hozzárendelve semmihez; néha elég, ha egyszerűen megváltoztatja a mutató által átadott karakterláncok egyikét.

Egy másik dolog az olyan függvények, mint például az strlen() vagy strcmp() , amelyek nem változtatják meg a paramétereket, hanem az eredmény érdekében hívódnak meg. Az strcmp() függvény betűnként (lexikográfiailag) összehasonlítja a két argumentum karakterláncot, és 0, -1 vagy 1 értéket ad vissza. Például az strcmp("boy", "body") hívása 1-et ad vissza, mert "y" betűkód több mint egy levél"d". Az strcmp("body", "boy") hívása -1-et ad vissza, mert az első érv lexikográfiailag kisebb, mint a második.

strtok() függvény

Az strtok() függvény segítségével egy karakterláncot különálló részekre (tokenekre) oszthatunk fel. Ennek a függvénynek a deklarációja így néz ki: char *strtok (char *, const char *) . A függvény első meghívásakor az első paraméter a felosztandó karakterlánc. A második paraméter a határoló karakterláncot adja meg. Ugyanazon sor további függvényhívásainál az első paraméternek NULL-nak kell lennie, mert a függvény már "emlékezett", hogy mivel működik. Vegyünk egy példát:

char str = "egy, kettő, három, négy, öt" ; char*sp; sp = strtok (str, ", " ) ; while (sp) ( elhelyezi (sp) ; sp = strtok (NULL, ", " ) ; )

A kód végrehajtásának eredményeként a következő szavak jelennek meg egy oszlopban:

Egy, kettő, három, négy, öt

Az strtok() első meghívásakor a függvény egy mutatót ad át a tömb első karakterére és egy határoló karakterláncot. E hívás után az str tömb megváltozik, csak az "one" szó marad benne, és a függvény egy mutatót is visszaad erre a szóra, ami az sp-hez van rendelve.

Bár a tömb többi részét elveszítettük a hívó függvényben, a tömb többi részére mutató mutató megmarad a strtok()-ban. Amikor a NULL értéket adjuk meg, a függvény "tudja", hogy ezzel a farokkal működik.

A karakterláncok részeinek másolása

Ha csak két karakterláncot kell összekapcsolnia, a probléma könnyen megoldható az strcat() függvény meghívásával, amely az első argumentum végéhez fűzi a másodikat. Egy hasonló függvény, az strncat(), n karaktert fűz hozzá a második karakterláncból az elsőhöz. n van megadva harmadik paraméterként.

Mi van, ha a helyzet bonyolultabb? Például van két nem üres sor, és össze kell kapcsolnia az első elejét és a második végét. Ezt a strcpy() függvény segítségével teheti meg, ha nem a karakterláncok első karaktereire ad át hivatkozásokat:

char s1[20] = "Peter Smith" , s2 = "Julia Roberts" ; strcpy (s1+ 5 , s2+ 5 ); tesz(ek1) ;

BAN BEN ez az eset"Peter Roberts" jelenik meg a képernyőn. Miért történt ez? Az első karakterlánc hatodik karakterére mutató mutatót átadtuk az strcpy() függvénynek. Ez oda vezetett, hogy másoláskor ennek a karakterláncnak a karakterei csak a 6-tól kezdődően íródnak felül, mert Az strcpy() nem "tud" semmit a korábbi karakterekről. A karakterláncnak csak egy része kerül átadásra második argumentumként is, amely az elsőbe másolódik.

Hogyan lehet beszúrni egy sort a másik közepébe? Ezt a problémát a harmadik "puffer" sor segítségével oldhatja meg, ahol először az első sort másolja, majd a másodikat, felülírva az első végét, majd csatolja az első végét. De ezt is megteheti:

char s1[20] = "egy három" , s2[20] = "kettő" ; strcpy (s2+ 3 , s1+ 3 ); strcpy (s1+4, s2); tesz(ek1) ;

Itt először az első végét másoljuk a második sorba, kiderül, hogy „két három”. Ezután a második sort az első sorba másolja, megkerülve annak elejét.

Néhány funkció leírása karakterláncokkal való munkához

Gyakorlat
Az alábbiakban néhány olyan függvény leírása található, amelyek karakterláncokon hajtanak végre műveleteket. Tervezzen és írjon kis programokat, amelyek bemutatják ezeknek a funkcióknak a működését.

  • char *strchr (const char *, int c) . Egy mutatót ad vissza a c karakter első előfordulására a karakterláncban. NULL értéket ad vissza, ha nincs ilyen karakter a karakterláncban.
  • char *strstr (const char *s2, const char *s1) . Egy mutatót ad vissza az s1 karakterlánc első előfordulására az s2 karakterláncban. Ha nincs egyezés, NULL értéket ad vissza.
  • char *strncpy (char *, const char *, size_t n) . A második karakterlánc n karakterét másolja az elsőbe.
  • size_t strspn (const char *, const char *) . Az első karakterlánc elejének hosszát adja vissza, amely tartalmazza a második karakterláncot alkotó karaktereket.

Szintaxis:

#beleértve
char *strtok(char *str, const char *sep);

Érvek:

str egy mutató a felosztandó karakterláncra.
A sep egy határoló karakterkészletet tartalmazó karakterláncra mutató mutató.

Visszatérési érték:

NULL - ha az str string nem osztható részekre.
Mutasson a karakterlánc kiválasztott részének első karakterére.

Leírás:

Az strtok függvény kibontja az str argumentum által mutatott karakterlánc következő részét, a sep argumentum által mutatott karakterláncban megadott határoló karakterek egyikével elválasztva. Az strtok függvény egymást követő hívása az str karakterlánc részekre (tokenekre) való felosztását eredményezi.

„Az strtok függvény első hívása egy elválasztandó karakterlánc elejét (str) és egy elválasztójeleket tartalmazó karakterlánc elejét (sep) határozza meg. Először ütés funkció egyenként iterálja végig a str string karaktereit, és olyan karaktert keres, amely nem szerepel a határoló karakterláncban sep. Ha az str stringben a sorvégi karaktert azelőtt találja meg, hogy a sep karakterláncban nem szereplő karaktert találtak volna, akkor az str karakterláncot nem lehet részekre osztani, és nulla mutatót (NULL) ad vissza. Ha ilyen karaktert találunk, az az str első részének kezdete.

Ezután az strtok függvény megkeresi a határolót, vagyis a karakterláncban szereplő karaktert sep. Ha nem található ilyen karakter, akkor az str karakterlánc egy résznek minősül, és az str karakterlánc későbbi felosztása null mutatót ad vissza. Ha ilyen karaktert találnak. majd egy null karakterrel (a sorvégi karakterrel) helyettesítjük. Ezután az strtok függvény megjegyzi az aktuális pozíciót (mutató arra a karakterre, amelytől a karakterlánc következő részének keresése kezdődik), és visszaad egy mutatót a karakterlánc első kiválasztott részének elejére.

Ha az strtok függvény nem nulla mutatót adott vissza, folytathatja az str részekre bontását. A karakterlánc felosztásának folytatásához a strtok függvény ismét meghívásra kerül, de a felosztandó karakterláncra mutató mutató helyett a NULL kerül megadásra első kiegészítésként. Ebben az esetben az strtok függvény folytatja a felosztást a megjegyzett címről. A particionálási algoritmus változatlan marad.

Példa:

A példában a „teszt1/teszt2/teszt3/teszt4” karakterlánc a „/” határolón lévő részekre van osztva az strtok függvény segítségével. A felosztott eredményt a rendszer a konzolra nyomtatja.

Eredmény:

Konzol kimenet:


4 válasz

Két dolog, amit tudni kell a strtok-ról. Mint említettük, "fenntartja a belső állapotot". Ráadásul ő elrontotta a vonalat, amivel eteted. Lényegében "\0"-t ír, ahol megtalálja az Ön által megadott jelölőt, és visszaadja a mutatót a karakterlánc elejére. Belsőleg fenntartja az utolsó token helyét; és ha legközelebb hívod, onnan indul.

Ennek fontos következménye, hogy nem használhatod az strtok-ot olyan karakterláncokon, mint a const char* "hello world"; , mivel a const char* karakterlánc tartalmának megváltoztatásakor hozzáférési szabálysértést kapsz.

Az a "jó" az strtok-ban, hogy valójában nem másol karakterláncokat, így nem kell extra memóriafoglalást kezelni stb. De ha nem érti a fentieket, akkor gondja lesz a használattal.

Példa. Ha a "this, is, string" van, az strtok egymást követő hívásai a következő mutatókat generálják (a ^ érték a visszatérési érték). Ne feledje, hogy a "\0" hozzáadódik ott, ahol a tokenek találhatók; ez azt jelenti, hogy az eredeti sor megváltozott:

T h i s , i s , a , s t r i n g \0 this,is,a,karakterlánc t h i s \0 i s , a , s t r i n g \0 this ^ t h i s \0 i s \0 r i s ^ i s \0 r i s , is s \0 a \ 0 s t r i n g \0 a ^ t h i s \0 i s \0 a \ 0 s t r i n g \0 karakterlánc ^

Remélem ennek van értelme.

Az strtok() függvény adatokat tárol a hívások között. Ezeket az adatokat használja, amikor NULL mutatóval hívja meg.

Az utolsó jogkivonat megtalálásának pontját a rendszer belsőleg tárolja egy függvényben, amelyet a következő híváskor kell használni (nincs szükség speciális könyvtári megvalósításra az adatösszeomlások megelőzésére).

strtok fenntartja a belső állapotot. Ha nem NULL-lal hívja meg, akkor újrainicializálja magát, hogy a megadott karakterláncot használja. Ha NULL-lal hívja meg, akkor ezt a karakterláncot és bármely más állapotot használja, amelyet jelenleg vissza kell adnia a következő tokent.

Az strtok működéséből adódóan meg kell győződnie arról, hogy a C futtatókörnyezet többszálas verziójához kapcsolódik, ha többszálú alkalmazást ír. Ez biztosítja, hogy minden szál saját belső állapotot kapjon az strtok számára.

Az strtok függvény egy belső statikus változóban tárolja az adatokat, amely meg van osztva az összes szál között.

A szál biztonsága érdekében használja az strtok_r-t

Vessen egy pillantást a static char *last;

Char * strtok(s, delim) register char *s; register const char *delim; ( regiszter char *spanp; register int c, sc; char *tok; statikus char *last; if (s == NULL && (s = last) == NULL) return (NULL); /* * Kihagyás (span) kezdő határolók (s += strspn(s, delim), sort of).*/ cont: c = *s++; for (spanp = (char *)delim; (sc = *spanp++) != 0;) ( if (c) == sc) goto cont; ) if (c == 0) ( /* nincsenek nem határoló karakterek */ last = NULL; return (NULL); ) tok = s - 1; /* * Keresési token (határolók keresése : s += strcspn(s, delim), fajta). * Ne feledje, hogy a delimnek egy NUL-nak kell lennie; megállunk, ha ezt is látjuk. */ for (;;) ( c = *s++; spanp = (char *)delim; do ( if ((sc = *spanp++) == c) ( if (c == 0) s = NULL; else s[-1] = 0; utolsó = s; return (tok); ) ) while (sc != 0); ) /* NOTREACHED */ )

Ossza meg

1) Megkeresi a következő tokent a null-végződésű bájtkarakterláncban, amelyre str mutatott. A határoló karaktereket a null byte karakterlánc azonosítja, amelyre a delim mutat.

Ezt a függvényt többszörös szorzásnak nevezik, hogy ugyanazon karakterláncból egymást követő tokeneket kapjunk.

  • Ha str! = NULL str ! = NULL , a hívást a rendszer az adott karakterlánc strtok első hívásaként kezeli. A függvény megkeresi az első karaktert Nem delim tartalmazza.
  • Ha nem található ilyen szimbólum, akkor nincsenek benne tokenek, és a függvény null mutatót ad vissza.
  • Ha találtak ilyen karaktert, akkor az lesz token start. A függvény ezután ettől a ponttól keresi a delimben található első karaktert.
    • Ha nem található ilyen karakter, az str-nek csak egy tokenje van, és az strtok jövőbeli hívásai null mutatót adnak vissza
    • Ha ilyen karaktert találtak, akkor az ki van cserélve a null karakter "\0" és a következő karakterre mutató mutató egy statikus helyen tárolódik a következő hívásokhoz.
  • A függvény ezután egy mutatót ad vissza a token elejére
  • Ha str == NULL , akkor a hívást úgy kezeljük, mint az strtok következő hívásait: a függvény onnan folytatódik, ahol az előző hívásban abbahagyta. A viselkedés ugyanaz, mintha az előzőleg tárolt mutató str-ként kerülne átadásra.

A viselkedés nem definiált, kivéve, ha az str vagy a delim egy null-végződésű bájtkarakterláncra mutató mutató.

2) Ugyanaz, mint (1), azzal a különbséggel, hogy minden lépés a *strmax-ba írja be a kikeresendő karakterek számát az str-ben, és a tokenizátor belső állapotát írja a *ptr-be. Az ismételt hívásoknak (nulla strmax-szal) át kell menniük az strmax és ptr értékeken az előző hívás által tárolt értékekkel. Ezenkívül futásidőben a következő hibákat a jelenlegi pedig az úgynevezett funkció beállítása kényszerkezelő anélkül, hogy bármit is tárolna a ptr által mutatott objektumban

  • strmax , delim vagy ptr - null mutató
  • egy nem kezdeti hívásnál (nulla str-vel) a *ptr egy null mutató
  • az első híváskor az *strmax nulla vagy nagyobb, mint RSIZE_MAX
  • a token keresés vége eléri az eredeti karakterlánc végét (a kezdeti *strmax értékkel mérve) anélkül, hogy null lezárást találna

A viselkedés definiálatlan, ha mind az str olyan karaktertömbre mutat, amely nem tartalmaz null karaktert, és az strmax olyan értékre mutat, amely nagyobb, mint a karaktertömb mérete. Mint minden határellenőrzéssel kapcsolatos függvény, az strtok_s is csak akkor garantáltan elérhető, ha az __STDC_LIB_EXT1__ implementáció által definiált, és ha a felhasználó __STDC_WANT_LIB_EXT1__ értéket definiál az 1. egész szám állandóhoz a string.h hozzáadása előtt.

lehetőségek

Visszatérési érték

Egy mutatót ad vissza a következő token elejére, vagy NULL-t, ha nincs több token.

A jegyzet

Ez a függvény destruktív: a str sztring elemeibe írja be a "\0" karaktereket. Konkrétan egy strtok literál nem használható az strtok első argumentumaként.

Az strtok minden hívása módosít egy statikus változót: nem szál biztonságos.

A legtöbb más tokenizátorral ellentétben az strtok határolói minden egymást követő tokennél eltérőek lehetnek, és még az előző tokenek tartalmától is függhetnek.

Az strtok_s függvény abban különbözik a POSIX strtok_r függvényétől, hogy a tokenizált karakterláncon kívül tárolja, és ellenőrzi a futási korlátokat.

példa

#define __STDC_WANT_LIB_EXT1__ 1 #include #beleértve int main(void) ( char input = "Egy madár jött le a sétán"; printf("A "%s" bemeneti karakterlánc elemzése\n", input); char *token = strtok(input, " "); while( token) ( puts(token); token = strtok(NULL, " "); ) printf("A bemeneti karakterlánc tartalma most: ""); for(size_t n = 0; n< sizeof input; ++n) input[n] ? printf("%c", input[n]) : printf("\\0"); puts("""); #ifdef __STDC_LIB_EXT1__ char str = "A bird came down the walk"; rsize_t strmax = sizeof str; const char *delim = " "; char *next_token; printf("Parsing the input string "%s"\n", str); token = strtok_s(str, &strmax, delim, &next_token); while(token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: ""); for(size_t n = 0; n < sizeof str; ++n) str[n] ? printf("%c", str[n]) : printf("\\0"); puts("""); #endif }

Lehetséges kimenet:

A bemeneti karakterlánc elemzése "Egy madár jött le a séta" Egy madár jött le a séta A beviteli karakterlánc tartalma most: "A\0bird\0come\0down\0the\0walk\0" A beviteli karakterlánc elemzése "Egy madár jött le a séta" Egy madár jött le a sétán A beviteli karakterlánc tartalma most: "A\0bird\0come\0down\0the\0walk\0"

  • C11 (ISO/IEC 9899:2011):
    • 7.24.5.8 Az strtok függvény (369-370. o.)
    • K.3.7.3.1 strtok_s függvény (p: 620-621)
  • C99 (ISO/IEC 9899:1999):
    • 7.21.5.8 A strtok függvény (332-333. o.)
  • C89/C90 (ISO/IEC 9899:1990):
    • 4.11.5.8 strtok függvény
megkeresi bármely karakter első helyét az egyik karakterláncban, egy másik karakterláncban
(funkció)

csak olyan karakterek, amelyek nem találhatók másik bájtkarakterláncban
(funkció)
a maximális kezdeti szegmens hosszát adja vissza, amely a következőből áll
csak karakterek találhatók egy másik bájtkarakterláncban
(funkció)

(C95) (C11)

széles zsinórban találja meg a következő tokent
(funkció)
C++ dokumentáció a strtok számára

Ha hibát észlel, jelöljön ki egy szövegrészt, és nyomja meg a Ctrl + Enter billentyűket
OSSZA MEG: