Spec-Zone.ru › C++

std::strtok

Определено в заголовочном файле <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"

См. также

strpbrk
находит первое вхождение любого символа из набора разделителей
(функция)
strcspn
возвращает длину максимального начального сегмента, состоящего
только из символов, отсутствующих в другой байтовой строке
(функция)
strspn
возвращает длину максимального начального сегмента, состоящего
только из символов, присутствующих в другой байтовой строке
(функция)
ranges::split_viewviews::split
(C++20)
представление view поддиапазонов, полученных путём разделения другого view с помощью разделителя
(шаблон класса) (объект-адаптер диапазона)
Документация C для strtok

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

Spec-Zone.ru

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