The correct way to use strtok_r
is as follows:
char* str = strdup(string);
char* save;
char* ptr = strtok_r(str, delim, &save);
while(ptr) {
puts(ptr);
ptr = strtok_r(NULL, delim, &save);
}
When trying to inspect what actually is stored in save
, I found it is just the rest of the unparsed string. So I tried to make the second call look like the first and wrote a wrapper as follows.
char* as_tokens(char** str, const char* const delim) {
return strtok_r(NULL, delim, str);
}
This can be used like below which is much less verbose. We don't have to differentiate between first call and rest.
char* str = strdup(string);
char* ptr;
while(ptr = as_tokens(&str, delim))
puts(ptr);
Are there any downsides in this approach? Am I causing any undefined behavior? I tried some edge cases and both approaches work similarly.
Online Compiler: https://wandbox.org/permlink/rkGiwXOUtzqrbMpP
P.S. Ignoring memory leaks for brevity.
Update
There already exists a function almost similar to my as_tokens
: strsep.
It differs in the case when there are consecutive delimiters. strsep
returns an empty string while as_tokens
(i.e strtok_r) treats them as one.