std::strtok
| Определено в заголовочном файле <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 с использованием разделителя (шаблон класса) (объект адаптера диапазона) | |
Документация C по strtok
| |