Namespaces
Variants

std:: strtok

From cppreference.net
Определено в заголовочном файле <cstring>
char * strtok ( char * str, const char * delim ) ;

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

Последовательность вызовов std::strtok разбивает строку, на которую указывает str , на последовательность токенов, каждый из которых ограничен символом из строки, на которую указывает delim . Каждый вызов в последовательности имеет цель поиска  :

  • Если str не является нулевым указателем, вызов является первым вызовом в последовательности. Целью поиска является строка байтов с нулевым завершающим символом, на которую указывает str .
  • Если str является нулевым указателем, вызов является одним из последующих вызовов в последовательности. Цель поиска определяется предыдущим вызовом в последовательности.

Каждый вызов в последовательности ищет в целевой строке поиска первый символ, который не содержится в строке разделителей , на которую указывает delim , строка разделителей может различаться от вызова к вызову.

  • Если такой символ не найден, то в целевой строке поиска нет токенов. Целевая строка поиска для следующего вызова в последовательности остается неизменной. [1]
  • Если такой символ найден, это начало текущего токена. std::strtok затем ищет оттуда первый символ, который содержится в строке разделителей.
    • Если такой символ не найден, текущий токен простирается до конца целевой строки поиска. Целевая строка поиска для следующего вызова в последовательности является пустой строкой. [2]
    • Если такой символ найден, он перезаписывается нулевым символом, который завершает текущий токен. Целевая строка поиска для следующего вызова в последовательности начинается со следующего символа.

Если str или delim не является указателем на байтовую строку с завершающим нулевым символом, поведение не определено.

  1. Токен может быть сформирован при последующем вызове с другой строкой-разделителем.
  2. При последующих вызовах больше не может быть сформировано токенов.

Содержание

Параметры

str - указатель на нуль-терминированную байтовую строку для токенизации
delim - указатель на нуль-терминированную байтовую строку, определяющую разделители

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

Возвращает указатель на первый символ следующей лексемы, или нулевой указатель, если лексемы отсутствуют.

Примечания

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

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

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

Возможная реализация

char* strtok(char* str, const char* delim)
{
    static char* buffer;
    if (str != nullptr)
        buffer = str;
    buffer += std::strspn(buffer, delim);
    if (*buffer == '\0')
        return nullptr;
    char* const tokenBegin = buffer;
    buffer += std::strcspn(buffer, delim);
    if (*buffer != '\0')
        *buffer++ = '\0';
    return tokenBegin;
}

Фактические реализации этой функции в библиотеках C++ делегируют вызовы библиотеке C, где она может быть реализована напрямую (как в MUSL libc ), или через свою реентерабельную версию (как в GNU libc ).

Пример

#include <cstring>
#include <iomanip>
#include <iostream>
int main() 
{
    char input[] = "one + two * (three - four)!";
    const char* delimiters = "! +- (*)";
    char* token = std::strtok(input, delimiters);
    while (token)
    {
        std::cout << std::quoted(token) << ' ';
        token = std::strtok(nullptr, delimiters);
    }
    std::cout << "\nContents of the input string now:\n\"";
    for (std::size_t n = 0; n < sizeof input; ++n)
    {
        if (const char c = input[n]; c != '\0')
            std::cout << c;
        else
            std::cout << "\\0";
    }
    std::cout << "\"\n";
}

Вывод:

"one" "two" "three" "four" 
Contents of the input string now:
"one\0+ two\0* (three\0- four\0!\0"

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

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