Spec-Zone.ru › C

strtok, strtok_s

Определено в заголовочном файле <string.h>
char* strtok( char* str, const char* delim );
(1) (до 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), за исключением следующих отличий:
  • При каждом вызове записывает в *strmax количество символов, оставшихся для просмотра в str, и записывает внутреннее состояние токенизатора в *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 соответствует этому определению strtok_r POSIX, а не strtok_s C11.

Пример

#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

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/string/byte/strtok

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API