strtok(3)

ИМЯ
strtok, strtok_r - извлечение элементов (токенов) из строки

LIBRARY
Standard C library (libc, -lc)

СИНТАКСИС
#include <string.h>

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

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

strtok_r():
    _POSIX_C_SOURCE
        || /* Glibc <= 2.19: */ _BSD_SOURCE || _SVID_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.

The strtok_r() function is a reentrant version of strtok(). The saveptr argument is a pointer to a char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

При первом вызове 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.

ЗАМЕЧАНИЯ
В некоторых реализациях значение *saveptr должно быть равно NULL при первом вызове strtok_r(), который используется для разбора str.

ДЕФЕКТЫ
Используйте данные функции с осторожностью. Учитывайте, что:

•   Эти функции изменяют свой первый аргумент.

•   Эти функции не могут использоваться со строками-константами.

•   Теряется идентичность байта-разделителя.

•   При анализе функция 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 <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    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[0]);
            exit(EXIT_FAILURE);
        }
        for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
            token = strtok_r(str1, argv[2], &saveptr1);
            if (token == NULL)
                break;
            printf("%d: %s\n", j, token);
            for (str2 = token; ; str2 = NULL) {
                subtoken = strtok_r(str2, argv[3], &saveptr2);
                if (subtoken == NULL)
                    break;
                printf("\t --> %s\n", subtoken);
            }
        }
        exit(EXIT_SUCCESS);
    }

Ещё один пример программы, использующей strtok(), можно найти в getaddrinfo_a(3).

СМ. ТАКЖЕ
index(3), memchr(3), rindex(3), strchr(3), string(3), strpbrk(3), strsep(3), strspn(3), strstr(3), wcstok(3)

ПЕРЕВОД
Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 (https://www.gnu.org/licenses/gpl-3.0.html) или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.