strtok_r() splits a mutable C string into nonempty tokens and keeps its continuation state in a pointer you provide. Start with the string, then pass NULL on later calls for that same parse. It edits the input in place, so it is unsuitable when you need to preserve the original text, empty fields, or the exact delimiter bytes.
How to use strtok_r()
Include <string.h> and pass a writable character array, a delimiter-byte set, and the address of a char * variable used as parser state. The first call receives the string; subsequent calls for that parse receive NULL as the first argument and reuse the same state variable. Each successful call returns a pointer into the input buffer; exhaustion returns NULL.
#include <string.h>
#include <stdio.h>
int main(void)
{
char input[] = "alpha,beta;gamma";
const char *delimiters = ",;";
char *saveptr;
char *token = strtok_r(input, delimiters, &saveptr);
while (token != NULL) {
puts(token);
token = strtok_r(NULL, delimiters, &saveptr);
}
return 0;
}
Here, either comma or semicolon separates tokens, so the output is alpha, beta, and gamma, each on its own line. The example uses an array rather than a string literal because the function modifies the buffer.
Keep each parse sequence together
For one string, keep the buffer and its saveptr unchanged until tokenization finishes. Start a new parse with a new initial string argument and state variable. When parsing multiple strings, give each active sequence its own state pointer; do not use a single saveptr for interleaved sequences.
#1 Best Overall
What does the delimiter argument mean?
delim describes a set of individual bytes, not a multi-byte separator substring. In ",;", either comma or semicolon is a delimiter. The function scans for any byte in that set and separates tokens at those bytes.
This distinction matters for formats where a separator is a sequence such as :: and must be recognized as a unit. A delimiter set containing : treats each colon independently, rather than matching the two-character sequence.
Does strtok_r() modify the original string?
Yes. It replaces delimiter bytes in the input buffer with NUL terminators so that each returned token can be treated as a C string. The buffer is therefore changed, and the identity of the delimiter byte at each boundary is lost. The function also skips runs of delimiters rather than returning empty tokens, so input such as a,,b does not yield an empty field between the commas.
Use another parsing approach if the input must remain unchanged, if repeated separators represent empty fields, or if you need to retain which separator appeared. Make a writable copy first if modifying the source text is acceptable so long as the original remains available.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →What is the difference between strtok() and strtok_r()?
| Property | strtok() |
strtok_r() |
|---|---|---|
| Continuation state | Uses internal static state, according to the Linux strtok(3) manual page. | Stores state through the caller-provided saveptr, according to the Linux strtok_r(3) manual page. |
| Independent concurrent parses | The Linux manual documents it as not thread-safe. | POSIX specifies thread-safe behavior when concurrent parses use unique state pointers for their respective strings. |
| Input and token behavior | Modifies the input and returns nonempty tokens. | Also modifies the input and returns nonempty tokens; the reentrant variant does not preserve separators or empty fields. |
The principal difference is who owns the continuation state. strtok_r() makes separate parse sequences independent when each has its own state, which is useful when parsing is interleaved or performed concurrently. This does not make it safe for multiple threads to modify or share the same input buffer without coordination; buffer ownership and synchronization remain the caller’s responsibility.
Is strtok_r() thread-safe?
POSIX.1-2017 says strtok_r() shall be thread-safe and uses a user-provided pointer to maintain state between calls scanning the same string. For concurrent parsing, use a distinct saveptr for each string sequence. Do not interpret that guarantee as permission for unsynchronized concurrent access to the same mutable buffer.
Linux and glibc portability
The Linux manual lists strtok_r() in POSIX.1-2008 and notes its historical inclusion in POSIX.1-2001. For glibc, the manual documents _POSIX_C_SOURCE as the feature-test macro for exposing the declaration. It also notes that glibc versions through 2.19 accepted _BSD_SOURCE or _SVID_SOURCE. These macro details are specific to glibc; check the documentation for the target C library and compilation environment.
References: Linux man-pages: strtok_r(3), man-pages 6.18; The Open Group / IEEE: strtok(3p), POSIX.1-2017; Linux man-pages: strtok(3).
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

