Namespaces
Variants

strtok, strtok_s

From cppreference.net
< c ‎ | string ‎ | byte
Определено в заголовке <string.h>
(1)
char * strtok ( char * str, const char * delim ) ;
(до C99)
char * strtok ( char * restrict str, const char * restrict delim ) ;
(начиная с C99)
char * strtok_s ( char * restrict str, rsize_t * restrict strmax,
const char * restrict delim, char ** restrict ptr ) ;
(2) (начиная с C11)

Токенизирует нуль-терминированную байтовую строку.

1) Последовательность вызовов strtok разбивает строку, на которую указывает str , на последовательность токенов, каждый из которых разделён символом из строки, на которую указывает delim . Каждый вызов в последовательности имеет цель поиска  :
  • Если str не является нулевым указателем, вызов является первым вызовом в последовательности. Целью поиска является строка байтов с нулевым завершителем, на которую указывает str .
  • Если str является нулевым указателем, вызов является одним из последующих вызовов в последовательности. Цель поиска определяется предыдущим вызовом в последовательности.
Каждый вызов в последовательности ищет в целевой строке поиска первый символ, который не содержится в строке разделителей , на которую указывает delim , строка разделителей может меняться от вызова к вызову.
  • Если такой символ не найден, то в целевой строке поиска нет токенов. Целевая строка поиска для следующего вызова в последовательности остается неизменной. [1]
  • Если такой символ найден, он является началом текущего токена. strtok затем ищет от этой позиции первый символ, который содержится в строке разделителей.
    • Если такой символ не найден, текущий токен простирается до конца целевой строки поиска. Целевая строка поиска для следующего вызова в последовательности является пустой строкой. [2]
    • Если такой символ найден, он заменяется нулевым символом, который завершает текущий токен. Целевая строка поиска для следующего вызова в последовательности начинается со следующего символа.
Если str или delim не является указателем на байтовую строку с завершающим нулевым символом, поведение не определено.
2) Аналогично (1) , за исключением следующих различий:
  • При каждом вызове записывает количество оставшихся для просмотра символов в str в * strmax и записывает внутреннее состояние токенизатора в * ptr .
  • Последующие вызовы в последовательности должны передавать strmax и ptr со значениями, сохраненными предыдущим вызовом.
  • Следующие ошибки обнаруживаются во время выполнения и вызывают установленную в данный момент функцию обработки ограничений , без сохранения каких-либо данных в объекте, на который указывает ptr :
    • strmax , delim , или ptr является нулевым указателем.
    • * ptr является нулевым указателем для последующего вызова в последовательности.
    • * strmax превышает RSIZE_MAX .
    • Конец найденной лексемы не находится в пределах первых * s1max символов целевой строки поиска.
Если оба str указывают на массив символов, в котором отсутствует нулевой символ, и strmax указывает на значение, которое больше размера этого массива символов, поведение не определено.
Как и все функции с проверкой границ, strtok_s гарантированно доступна только если реализация определяет __STDC_LIB_EXT1__ и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <string.h> .
  1. Токен может быть сформирован при последующем вызове с другой строкой-разделителем.
  2. При последующих вызовах больше не может быть сформировано токенов.

Содержание

Параметры

str - указатель на байтовую строку с нулевым завершителем для токенизации
delim - указатель на байтовую строку с нулевым завершителем, определяющую разделители
strmax - указатель на объект, изначально содержащий размер str : strtok_s сохраняет количество символов, оставшихся для обработки
ptr - указатель на объект типа char * , который используется функцией strtok_s для хранения её внутреннего состояния

Возвращаемое значение

1) Возвращает указатель на первый символ следующей лексемы, или нулевой указатель, если лексемы отсутствуют.
2) Возвращает указатель на первый символ следующей лексемы, или нулевой указатель, если лексема отсутствует или произошло нарушение ограничений времени выполнения.

Примечание

Эта функция является деструктивной: она записывает ' \0 ' символы в элементах строки str . В частности, строковый литерал не может быть использован в качестве первого аргумента функции strtok .

Каждый вызов strtok изменяет статическую переменную: не является потокобезопасным.

В отличие от большинства других токенизаторов, разделители в strtok могут быть разными для каждого последующего токена и могут даже зависеть от содержимого предыдущих токенов.

Функция strtok_s отличается от POSIX-функции strtok_r защитой от записи за пределами токенизируемой строки и проверкой ограничений времени выполнения. Сигнатура Microsoft CRT strtok_s соответствует этому определению POSIX strtok_r , а не C11 strtok_s .

Пример

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
int main(void)
{
    char input[] = "A bird came down the walk";
    printf("Parsing the input string '%s'\n", input);
    char* token = strtok(input, " ");
    while (token)
    {
        puts(token);
        token = strtok(NULL, " ");
    }
    printf("Contents of the input string now: '");
    for (size_t n = 0; n < sizeof input; ++n)
        input[n] ? putchar(input[n]) : fputs("\\0", stdout);
    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] ? putchar(str[n]) : fputs("\\0", stdout);
    puts("'");
#endif
}

Возможный вывод:

Parsing the input string 'A bird came down the walk'
A
bird
came
down
the
walk
Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0'
Parsing the input string 'A bird came down the walk'
A
bird
came
down
the
walk
Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0'

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 7.24.5.8 Функция strtok (стр.: TBD)
  • K.3.7.3.1 Функция strtok_s (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.24.5.8 Функция strtok (стр.: TBD)
  • K.3.7.3.1 Функция strtok_s (стр.: TBD)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.24.5.8 Функция strtok (стр: 369-370)
  • K.3.7.3.1 Функция strtok_s (стр: 620-621)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.21.5.8 Функция strtok (стр: 332-333)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.11.5.8 Функция strtok

Смотрите также

находит первое вхождение любого символа из одной строки в другой строке
(функция)
возвращает длину максимального начального сегмента, который состоит
только из символов, не найденных в другой байтовой строке
(функция)
возвращает длину максимального начального сегмента, который состоит
только из символов, найденных в другой байтовой строке
(функция)
(C95) (C11)
находит следующую лексему в широкой строке
(функция)
C++ documentation для strtok