Функції strtok. Як працює функція strtok у C? Приклад: вихідний код програми

Інші Alias

strtok

ОГЛЯД

#include

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);

Вимоги макросу тестування властивостей glibc (див. feature_test_macros(7)):

strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

ОПИС

Функція strtok() поділяє рядок на послідовність нуля чи більше непустих токенів. При першому виклику strtok() аналізований рядок потрібно вказувати в аргументі str. У кожному наступному виклику, в якому аналізується цей рядок, значення strмає бути NULL.

В аргументі delimзадається набір байт, які вважаються роздільниками токенів в аналізованому рядку. Викликаючий може вказувати різні рядки в delimу наступних викликах під час аналізу того ж рядка.

Кожен виклик strtok() повертає покажчик на рядок, що завершується null, який містить наступний токен. Цей рядок не включає байт-розділювач. Якщо більше токенів немає, то strtok() повертає NULL.

Послідовність дзвінків strtok(), що оперують одним рядком, підтримує покажчик, який визначає точку, з якої починається пошук наступного токена. Перший виклик strtok() призначає цьому покажчику посилання на перший байт рядка. Початок наступного токена визначається пошуком вперед strнаступного байта не роздільника. Якщо байт знайдено, він береться як початок наступного токена. Якщо такий байт не знайдено, то токенів більше немає strtok() повертає NULL (для порожнього рядка або що складається тільки з роздільників у цьому випадку NULL повернеться під час першого виклику strtok()).

Кінець кожного токена знаходиться пошуком вперед, що триває доти, доки не буде знайдено байт-розділювач або завершальний байт null ("\0"). Якщо знайдено байт-розділювач, він замінюється байтом null для завершення поточного токена, і strtok() зберігає покажчик на наступний байт; цей покажчик буде використаний як початкова точка при пошуку наступного токена. В цьому випадку strtok() повертає покажчик початку знайденого токена.

З опису вище випливає, що послідовність з двох і більше безперервних байтів-розділювачів у рядку, що переглядається, вважається одним роздільником, а байти-розділювачі на початку або кінці рядка ігноруються. Іншими словами, токени, що повертаються strtok() - Завжди не порожні рядки. Тобто, наприклад, якщо є рядок « aaa;; bbb,», то наступні виклики strtok() із заданими роздільниками рядків « ;, » повернули б рядки « aaa» та « bbb», а потім покажчик null.

Функція strtok_r() є реентерабельною версією strtok(). Аргумент saveptrє вказівником на змінну char *яка використовується всередині strtok_r() для врахування контексту між наступними викликами при аналізі одного і того ж рядка.

При першому виклику strtok_r() значення strмає вказувати на аналізований рядок, а значення saveptrігнорується. При наступних дзвінках значення strмає бути NULL, а значення saveptrне повинно змінюватися з попереднього дзвінка.

Одночасно можуть аналізуватися різні рядки при кількох запусках strtok_r() з різними аргументами saveptr.

ПОВЕРНЕНИЙ ЗНАЧЕННЯ

Функції strtok() та strtok_r() повертають покажчик на наступний токен або NULL, якщо більше токенів немає.

АТРИБУТИ

Опис термінів даного розділу дивіться у attributes(7).
Інтерфейс Атрибут Значення
strtok() нешкідливість у ниткахнебезпечно (MT-Unsafe race:strtok)
strtok_r() нешкідливість у ниткахнешкідливо (MT-Safe)

ВІДПОВІДНІСТЬ СТАНДАРТАМ

strtok() POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. strtok_r() POSIX.1-2001, POSIX.1-2008.

Дефекти

Використовуйте ці функції з обережністю. Зважайте на те, що: * Ці функції змінюють свій перший аргумент. * Ці функції не можуть використовуватися з рядками-константами. * Втрачається ідентичність байта-розділювача. * При аналізі функція strtok() використовує статичний буфер, тому не є безпечним для ниток. Використовуйте strtok_r() в цьому випадку.

ПРИКЛАД

У програмі, наведеній далі, використовуються вкладені цикли, які викликають strtok_r() для поділу рядка на складові її токени. У першому параметрі командного рядказадається аналізований рядок. У другому параметрі задається байт(и)- роздільник, який використовується для поділу рядка на складові токени. У третьому параметрі вказується байт(и)- роздільник, який використовується для поділу «складових» токенів на підтокени.

Приклад результату виведення програми:

$./a.out "a/bbb///cc;xxx:yyy:" ":;" "/" 1: a/bbb///cc --> a --> bbb --> cc 2: xxx --> xxx 3: yyy --> yyy

Вихідний код програми

#include #include #include int main(int argc, char *argv) ( char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j; if (argc != 4) ( fprintf(stderr, "Використання: % s string delim subdelim\n", argv); exit(EXIT_FAILURE); ) for (j = 1, str1 = argv; ; j++, str1 = NULL) ( token = strtok_r(str1, argv, &saveptr1); if (token = = NULL) break; printf("%d: %s\n", j, token); NULL) break; printf(" --> %s\n", subtoken); ) ) exit(EXIT_SUCCESS); )

Ще один приклад програми, яка використовує strtok(), можна знайти в getaddrinfo_a(3).

Функція strtok() повертає покажчик на наступну лексему в рядку, що адресується параметром str1. Символи, що утворюють рядок, що адресується параметром str2, є роздільниками, які визначають лексему. За відсутності лексеми, що підлягає поверненню, повертається нульовий покажчик.

У версії С99 до параметрів str1 та str2 застосовано кваліфікатор restrict.

Щоб розділити рядок на лексеми, при першому виклику функції strtok() параметр str1 повинен вказувати на початок цього рядка. Під час наступних дзвінків функції як параметр str1 потрібно використовувати нульовий покажчик. У цьому випадку повний рядок модифікуватиметься при кожному виклику функції.

При кожному зверненні до функції strtok() можна використовувати різні набори лексемних розділювачів.

Функція strtok() надає засіб, що дозволяє скоротити рядок до його частин. Наприклад, наступна програма поділяє на лексеми рядок "One, two, and three".

#include #include int main (void) char * p; p = strtok("One, two, and three.", ","); printf(p); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p), return 0; )

Результат роботи цієї програми має такий вигляд.

One | два | і | three

Зверніть увагу, як функція strtok() спочатку викликається з вихідним рядком, але в наступних її викликах як перший аргумент використовується значення NULL. Функція strtok() підтримує внутрішній покажчик рядка, що обробляється. Якщо перший аргумент функції strtok() вказує на рядок, внутрішній покажчик встановлюється на початок цього рядка. Якщо перший аргумент дорівнює NULL, функція strtok() продовжує процес обробки попереднього рядка, починаючи з позиції, запам'ятованої на попередньому кроці, і просуває внутрішній покажчик у міру отримання чергової лексеми. Таким чином, функція strtok() "проходить" весь рядок. Також зверніть увагу на те, як змінюється рядок, що задає роздільники, при першому та наступних викликах функції. Під час кожного виклику роздільники можуть визначатися по-різному.

#include char *strtok(char * str1, const char * str2);

Функція strtok() повертає покажчик на наступну лексему в рядку, що адресується параметром str1. Символи, що утворюють рядок, що адресується параметром str2, є роздільники, які визначають лексему. За відсутності лексеми, що підлягає поверненню, повертається нульовий покажчик.

У версії С99 до параметрів str1і str2застосований кваліфікатор restrict.

Щоб розділити рядок на лексеми, при першому виклику функції strtok() параметр str1повинен зазначати початок цього рядка. При наступних дзвінках функції як параметр str1потрібно використовувати нульовий покажчик. Цим способом весь рядок розбивається на лексеми.

При кожному зверненні до функції strtok() можна використовувати різні набори роздільників.

приклад

Ця програма розбиває рядок «Травка зеленіє, сонечко блищить» на лексеми, роздільниками яких є прогалини та коми. В результаті вийде

Травка | зеленіє | сонечко | блищить # include #include int main(void) ( char *p; p = strtok("Травка зеленіє, сонечко блищить", " "); printf(p); do ( p = strtok("\0", ", "); if(p) ) printf("|%s", p); ) while(p); return 0; )

Синтаксис:

#include
char * strtok (char * str, const char * sep);

Аргументи:

str - покажчик на рядок, що розбивається.
sep – покажчик на рядок, що містить набір символів роздільників.

Значення, що повертається:

NULL – якщо рядок str не можна розділити на частини.
Вказівник на перший символ виділеної частини рядка.

Опис:

Функція strtok виділяє чергову частину рядка, яку вказує аргумент str, відокремлену одним із символів роздільників зазначених у рядку, на яку вказує аргумент sep. Послідовний виклик функції strtok призводить до розбиття рядка str частини (лексеми).

«При першому виклику функції strtok вказується початок рядка (str), що розділяється, і початок рядка, що містить роздільники (sep). На початку функція strtok по черзі переглядає символи рядка str і шукає символ, що не міститься у рядку розділів sep. Якщо у рядку str символ кінця рядка зустрінутий раніше, ніж було знайдено символ, що не входить до рядка sep, то розділити рядок str на частини не можна і повертається нульовий покажчик (NULL). Якщо такий символ знайдено, він вважається початком першої частини рядка str.

Далі функція strtok шукає роздільник, тобто символ, що входить до рядка sep. Якщо такий символ не знайдено, то вважається, що рядок str складається з однієї частини і наступне поділу рядка str повертатимуть нульовий покажчик. Якщо такий символ знайдено. він замінюється нульовим символом (символом кінця рядка). Далі функція strtok запам'ятовує поточну позицію (покажчик на символ, з якого буде починатися пошук наступної частини рядка) і повертає покажчик початку першої виділеної частини рядка.

Якщо функція strtok повернула не нульовий покажчик, можна продовжити розбиття рядка str на частини. Для продовження розбиття рядка, повторно викликається функція strtok, але замість вказівника на рядок, що розбивається, як перший аугмент вказується NULL. У цьому випадку функція strtok продовжить розбиття із запам'ятованої адреси. Алгоритм розбиття при цьому залишиться той самий.

Приклад:

У прикладі, рядок «test1/test2/test3/test4» розбивається на частини по роздільнику “/” за допомогою функції strtok. Результат розбиття виводиться на консоль.

Результат:

Виведення в консоль:





Top