Функции для обработки строк. Описание функций языка си Strtok s c описание

Other Alias

strtok

ОБЗОР

#include

char *strtok(char * str , const char * delim );
char *strtok_r(char * str , const char * delim , char ** saveptr );

Требования макроса тестирования свойств для glibc (см. feature_test_macros (7)):

strtok_r (): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

ОПИСАНИЕ

Функция strtok () разделяет строку на последовательность нуля или более непустых токенов. При первом вызове strtok () анализируемую строку нужно указывать в аргументе str . В каждом последующем вызове, в котором анализируется эта же строка, значение str должно быть NULL.

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

Каждый вызов strtok () возвращает указатель на строку, завершающуюся null, которая содержит следующий токен. Эта строка не включает байт-разделитель. Если больше токенов нет, то strtok () возвращает NULL.

Последовательность вызовов strtok (), оперирующих одной строкой, поддерживает указатель, который определяет точку, с которой начинается поиск следующего токена. Первый вызов strtok () назначает этому указателю ссылку на первый байт строки. Начало следующего токена определяется поиском вперёд в str следующего байта не разделителя. Если байт найден, то он берётся в качестве начала следующего токена. Если такой байт не найден, то токенов больше нет и strtok () возвращает NULL (для пустой строки или состоящей только из разделителей в этом случае NULL вернётся при первом вызове strtok ()).

Конец каждого токена находится поиском вперёд, длящемся до тех пор, пока не будет найден байт-разделитель или завершающий байт null ("\0"). Если найден байт-разделитель, то он заменяется байтом null для завершения текущего токена, и strtok () сохраняет указатель на следующий байт; этот указатель будет использован в качестве начальной точки при поиске следующего токена. В этом случае strtok () возвращает указатель на начало найденного токена.

Из описания выше следует, что последовательность из двух и более непрерывных байтов-разделителей в просматриваемой строке считается одним разделителем, а байты-разделители в начале или конце строки игнорируются. Другими словами, токены, возвращаемые strtok () - всегда не пустые строки. То есть, например, если есть строка «aaa;;bbb, », то последующие вызовы strtok () с заданными разделителями строк «;, » вернули бы строки «aaa » и «bbb », а затем указатель null.

Функция strtok_r () является реентерабельной версией strtok (). Аргумент saveptr является указателем на переменную char * , которая используется внутри strtok_r () для учёта контекста между последующими вызовами при анализе одной и той же строки.

При первом вызове strtok_r () значение str должно указывать на анализируемую строку, а значение saveptr игнорируется. При последующих вызовах значение str должно быть NULL, а значение saveptr не должно изменяться с момента предыдущего вызова.

Одновременно могут анализироваться разные строки при нескольких запусках strtok_r () с различными аргументами saveptr .

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Функции strtok () и strtok_r () возвращают указатель на следующий токен или NULL, если больше токенов нет.

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes (7).
Интерфейс Атрибут Значение
strtok () безвредность в нитях небезопасно (MT-Unsafe race:strtok)
strtok_r () безвредность в нитях безвредно (MT-Safe)

СООТВЕТСТВИЕ СТАНДАРТАМ

strtok () POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. strtok_r () POSIX.1-2001, POSIX.1-2008.

ДЕФЕКТЫ

Используйте данные функции с осторожностью. Учитывайте, что: * Эти функции изменяют свой первый аргумент. * Эти функции не могут использоваться со строками-константами. * Теряется идентичность байта-разделителя. * При анализе функция strtok () использует статический буфер, поэтому не является безопасной для нитей. Используйте strtok_r () в этом случае.

ПРИМЕР

В программе, представленной далее, используются вложенные циклы, которые вызывают strtok_r () для разделения строки на составляющие её токены. В первом параметре командной строки задаётся анализируемая строка. Во втором параметре задаётся байт(ы)- разделитель, который используется для деления строки на «составные» токены. В третьем параметре указывается байт(ы)- разделитель, который используется для разделения «составных» токенов на подтокены.

Пример результата вывода программы:

$ ./a.out "a/bbb///cc;xxx:yyy:" ":;" "/" 1: a/bbb///cc --> a --> bbb --> cc 2: xxx --> xxx 3: yyy --> yyy

Исходный код программы

#include #include #include int main(int argc, char *argv) { char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j; if (argc != 4) { fprintf(stderr, "Использование: %s string delim subdelim\n", argv); exit(EXIT_FAILURE); } for (j = 1, str1 = argv; ; j++, str1 = NULL) { token = strtok_r(str1, argv, &saveptr1); if (token == NULL) break; printf("%d: %s\n", j, token); for (str2 = token; ; str2 = NULL) { subtoken = strtok_r(str2, argv, &saveptr2); if (subtoken == NULL) break; printf(" --> %s\n", subtoken); } } exit(EXIT_SUCCESS); }

Ещё один пример программы, использующей strtok (), можно найти в getaddrinfo_a (3).

Описание

Функция strtok выполняет поиск лексем в строке string . Последовательность вызовов этой функции разбивают строку string на лексемы, которые представляют собой последовательности символов, разделенных символами разделителями.

На первый вызов, функция принимает строку string в качестве аргумента, чей первый символ используется в качестве начальной точки для поиска лексем. В последующие вызовы, функция ожидает нулевого указателя и использует позицию сразу после окончания последней лексемы как новое местонахождение для сканирования.

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

Этот конечный маркер автоматически заменяется нулевым символом, и лексема возвращается функцией. После этого, следующие вызовы функции strtok начинаются с этого нулевого символа.

Параметры:

  • string
    Строка для поиска в ней лексем. Содержание этой строки будет изменено, она разбивается на более мелкие строки (лексемы). Данный параметр может содержать нулевой указатель, в этом случае функция продолжает сканирование с того места, где был остановлен предыдущий успешный вызов функции.
  • delim
    Строка, содержащая разделители. Они могут варьироваться от одного вызова к другому вызову функции.

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

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

Пример: исходный код программы

//пример использования функции strtok #include #include int main () { char str = "Особенности национальной рыбалки - художественный, комедийный фильм."; std::cout << "Разделение строки "" << str << "" на лексемы:n"; char * pch = strtok (str," ,.-"); // во втором параметре указаны разделитель (пробел, запятая, точка, тире) while (pch != NULL) // пока есть лексемы { std::cout << pch << "n"; pch = strtok (NULL, " ,.-"); } return 0; }

Синтаксис:

#include
char *strtok(char *str, const char *sep);

Аргументы:

str – указатель на разбиваемую строку.
sep – указатель на строку, содержащую набор символов разделителей.

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

NULL – если строку str невозможно разделить на части.
Указатель на первый символ выделенной части строки.

Описание:

Функция strtok выделяет очередную часть строки, на которую указывает аргумент str, отделенную одним из символов разделителей указанных в строке, на которую указывает аргумент sep. Последовательный вызов функции strtok приводит к разбиению строки str на части (лексемы).

«При первом вызове функции strtok указывается начало разделяемой строки (str) и начало строки, содержащей разделители (sep). В начале функция strtok поочередно просматривает символы строки str и ищет символ, не содержащейся в строке разделителей sep. Если в строке str символ конца строки встречен раньше, чем был найден символ не входящий в строку sep, то разделить строку str на части нельзя и возвращается нулевой указатель (NULL). Если такой символ найден, он считается началом первой части строки str.»

Далее функция strtok ищет разделитель, то есть символ, входящий в строку sep. Если такой символ не найден, то считается, что строка str состоит из одной части и последующее разделения строки str будут возвращать нулевой указатель. Если такой символ найден. то он заменяется нулевым символом (символом конца строки). Далее функция strtok запоминает текущую позицию (указатель на символ, с которого будет начинаться поиск следующей части строки) и возвращает указатель на начало первой выделенной части строки.

Если функция strtok вернула не нулевой указатель, можно продолжить разбиение строки str на части. Для продолжения разбиения строки, повторно вызывается функция strtok, но вместо указателя на разбиваемую строку в качестве первого аугмента указывается NULL. В этом случае функция strtok продолжит разбиение с запомненного адреса. Алгоритм разбиения при этом останется тот же.

Пример:

В примере, в строка «test1/test2/test3/test4» разбивается на части по разделителю “/” с помощью функции strtok. Результат разбиения выводится на консоль.

Результат:

Вывод в консоль:


Функция strtok() возвращает указатель на следующую лексему в строке, адресуемой параметром str1. Символы, образующие строку, адресуемую параметром str2, представляют собой разделители, которые определяют лексему. При отсутствии лексемы, подлежащей возврату, возвращается нулевой указатель.

В версии С99 к параметрам str1 и str2 применен квалификатор restrict.

Чтобы разделить некоторую строку на лексемы, при первом вызове функции strtok() параметр str1 должен указывать на начало этой строки. При последующих вызовах функции в качестве параметра str1 нужно использовать нулевой указатель. В этом случае полная строка будет модифицироваться при каждом вызове функции.

При каждом обращении к функции strtok() можно использовать различные наборы разделителей лексем.

Функция strtok() предоставляет средство, позволяющее сократить строку до составляющих ее частей. Например, следующая программа разделяет на лексемы строку "One, two, and three".

#include #include int main(void) char *p; p = strtok("One, two, and three.", ","); printf(p); do { p = strtok(NULL, ",. "); if(p) printf("|%s", p); } while(p), return 0; }

Результат работы этой программы имеет следующий вид.

One | two | and | three

Обратите внимание, как функция strtok() сначала вызывается с исходной строкой, но в последующих ее вызовах в качестве первого аргумента используется значение NULL. Функция strtok() поддерживает внутренний указатель обрабатываемой строки. Если первый аргумент функции strtok() указывает на строку, внутренний указатель устанавливается в начало этой строки. Если первый аргумент равен значению NULL, функция strtok() продолжает процесс обработки предыдущей строки, начиная с позиции, запомненной на предыдущем шаге, и продвигает внутренний указатель по мере получения очередной лексемы. Таким образом, функция strtok() "проходит" всю строку. Также обратите внимание на то, как изменяется строка, задающая разделители, при первом и последующих вызовах функции. При каждом вызове разделители могут определяться по-разному.

#include char *strtok(char *str1 , const char *str2 );

Функция strtok() возвращает указатель на следующую лексему в строке, адресуемой параметром str1 . Символы, образующие строку, адресуемую параметром str2 , представляют собой разделители, которые определяют лексему. При отсутствии лексемы, подлежащей возврату, возвращается нулевой указатель.

В версии С99 к параметрам str1 и str2 применен квалификатор restrict .

Чтобы разделить некоторую строку на лексемы, при первом вызове функции strtok() параметр str1 должен указывать на начало этой строки. При последующих вызовах функции в качестве параметра str1 нужно использовать нулевой указатель. Этим способом вся строка разбивается на лексемы.

При каждом обращении к функции strtok() можно использовать различные наборы разделителей.

Пример

Эта программа разбивает строку «Травка зеленеет, солнышко блестит» на лексемы, разделителями которых служат пробелы и запятые. В результате получится

Травка|зеленеет|солнышко|блестит #include #include int main(void) { char *p; p = strtok("Травка зеленеет, солнышко блестит", " "); printf(p); do { p = strtok("\0", ", "); if(p) printf("|%s", p); } while(p); return 0; }