strtok, strtok_r -
извлечение
элементов
(токенов) из
строки
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);
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()).
The end of each token is found by scanning forward until either the next
delimiter byte is found or until the terminating null byte ('\0') is
encountered. If a delimiter byte is found, it is overwritten with a null byte
to terminate the current token, and
strtok() saves a pointer to the
following byte; that pointer will be used as the starting point when searching
for the next token. In this case,
strtok() returns a pointer to the
start of the found token.
Из
описания
выше
следует,
что
последовательность
из двух и
более
непрерывных
байтов-разделителей
в
просматриваемой
строке
считается
одним
разделителем,
а
байты-разделители
в начале
или конце
строки
игнорируются.
Другими
словами,
токены,
возвращаемые
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, 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).
memchr(3),
strchr(3),
string(3),
strpbrk(3),
strsep(3),
strspn(3),
strstr(3),
wcstok(3)
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]