правильный способ использования strtok_r
заключается в следующем:
char* str = strdup(string);
char* save;
char* ptr = strtok_r(str, delim, &save);
while(ptr) {
puts(ptr);
ptr = strtok_r(NULL, delim, &save);
}
При попытке проверить, что на самом деле хранится в save
, я обнаружил, что это просто остальныенеразобранной строки.Поэтому я попытался сделать второй вызов похожим на первый и написал обертку следующим образом:
char* as_tokens(char** str, const char* const delim) {
return strtok_r(NULL, delim, str);
}
Это можно использовать, как показано ниже, что гораздо менее многословно.Нам не нужно проводить различие между первым вызовом и отдыхом.
char* str = strdup(string);
char* ptr;
while(ptr = as_tokens(&str, delim))
puts(ptr);
Есть ли недостатки в этом подходе?Я вызываю неопределенное поведение?Я пробовал некоторые крайние случаи, и оба подхода работают одинаково.
Онлайн-компилятор: https://wandbox.org/permlink/rkGiwXOUtzqrbMpP
PS Игнорирование утечек памяти для краткости.
Обновление
Уже существует функция, почти аналогичная моей as_tokens
: strsep .Отличается в случае, когда есть последовательные разделители.strsep
возвращает пустую строку, тогда как as_tokens
(т.е. strtok_r) обрабатывает их как единое целое.