close
Пространства имён
Варианты
Действия

std::strtok

Материал из cppreference.com
 
 
 
Однобайтовые строки с завершающим нулём
Функции
Манипуляции с символами
Преобразование в числовые форматы
(C++11)(C++11)
(C++11)(C++11)
Манипуляции со строками
Проверка строки
Манипуляции с памятью
Разное
 
<tbody> </tbody>
Определено в заголовочном файле <cstring>
char* strtok( char* str, const char* delim );

Находит следующий токен в строке байтов с нулевым завершающим символом, на которую указывает str. Символы-разделители идентифицируются строкой байтов с нулевым завершающим символом, на которую указывает delim.

Эта функция предназначена для многократного вызова для получения последовательных токенов из одной и той же строки.

  • Если str не является нулевым указателем, вызов рассматривается как первый вызов strtok для этой конкретной строки. Функция ищет первый символ, который не содержится в delim.
  • Если такой символ не найден, то в str вообще нет токенов и функция возвращает нулевой указатель.
  • Если такой символ был найден, это начало токена. Затем функция с этого места ищет первый символ, который содержится в delim.
  • Если такой символ не найден, str имеет только один токен, и будущие вызовы strtok вернут нулевой указатель.
  • Если такой символ был найден, он заменяется нулевым символом '\0', а указатель на следующий символ сохраняется в статическом расположении для последующих вызовов.
  • Затем функция возвращает указатель на начало токена.
  • Если str является нулевым указателем, вызов рассматривается как последующий вызов strtok: функция продолжает работу с того места, где она остановилась при предыдущем вызове. Поведение такое же, как если бы ранее сохранённый указатель был передан как str.

Параметр

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

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

Указатель на начало следующего токена или nullptr, если токенов больше нет.

Примечание

Эта функция деструктивна: она записывает символы '\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 << "\nСодержимое входной строки сейчас:\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" 
Содержимое входной строки сейчас:
"one\0+ two\0* (three\0- four\0!\0"

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

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