C strtok_s function
last modified April 8, 2025
String tokenization is a common operation in C programming, and strtok_s
is the safer version of the strtok
function for splitting strings.
This tutorial covers strtok_s
in depth, including its syntax, usage,
and advantages over strtok
. We'll explore practical examples and
discuss why strtok_s
should be preferred in modern C programming.
Understanding strtok_s
helps write more secure and reliable string
processing code.
What Is strtok_s?
The strtok_s
function is a safer alternative to strtok
for splitting strings into tokens. It's part of the C11 standard's Annex K
bounds-checking interfaces. strtok_s
adds a context parameter to
maintain state between calls, making it thread-safe. It also performs runtime
constraints checking. Unlike strtok
, it can detect invalid
parameters and buffer overflows. Always prefer strtok_s
in new code
where security matters.
Basic strtok_s Usage
This example demonstrates basic string tokenization using strtok_s
.
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main() { char str[] = "apple,banana,cherry"; char *token; char *context = NULL; const char *delim = ","; // First call to strtok_s token = strtok_s(str, delim, &context); while (token != NULL) { printf("Token: %s\n", token); // Subsequent calls with NULL as first argument token = strtok_s(NULL, delim, &context); } return 0; }
This code splits a comma-separated string into individual tokens.
strtok_s
maintains its state in the context
pointer.
The first call uses the string to tokenize, while subsequent calls use NULL.
Each call returns a pointer to the next token or NULL when done. The context
parameter makes this thread-safe compared to strtok
.
Tokenizing with Multiple Delimiters
strtok_s
can handle multiple delimiter characters, as shown here.
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main() { char str[] = "apple;banana cherry,orange"; char *token; char *context = NULL; const char *delim = "; ,"; token = strtok_s(str, delim, &context); while (token != NULL) { printf("Fruit: %s\n", token); token = strtok_s(NULL, delim, &context); } return 0; }
This example tokenizes a string using multiple delimiters: semicolon, space, and
comma. strtok_s
treats any sequence of these characters as a single
delimiter. The output shows all fruits separated regardless of which delimiter
was used. This flexibility makes strtok_s
useful for parsing
complex input. Always ensure your delimiter string includes all possible
separators.
Handling Empty Tokens
This example demonstrates how strtok_s
handles consecutive
delimiters.
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main() { char str[] = "apple,,banana,,,cherry"; char *token; char *context = NULL; const char *delim = ","; int count = 0; token = strtok_s(str, delim, &context); while (token != NULL) { printf("Token %d: '%s'\n", ++count, token); token = strtok_s(NULL, delim, &context); } printf("Total tokens: %d\n", count); return 0; }
When consecutive delimiters appear, strtok_s
skips empty tokens
between them. This example has multiple commas in sequence, but only three
non-empty tokens are found. If you need to preserve empty tokens, consider
alternative approaches like strsep
or manual parsing. The context
parameter ensures correct state tracking even with complex delimiter patterns.
Tokenizing in Nested Loops
This example shows how to use strtok_s
in nested tokenization.
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main() { char data[] = "name=John;age=30;city=New York"; char *outer_token; char *outer_context = NULL; char *inner_token; char *inner_context = NULL; const char *outer_delim = ";"; const char *inner_delim = "="; outer_token = strtok_s(data, outer_delim, &outer_context); while (outer_token != NULL) { printf("Pair: %s\n", outer_token); inner_token = strtok_s(outer_token, inner_delim, &inner_context); printf(" Key: %s\n", inner_token); inner_token = strtok_s(NULL, inner_delim, &inner_context); printf(" Value: %s\n", inner_token); outer_token = strtok_s(NULL, outer_delim, &outer_context); } return 0; }
This code demonstrates nested tokenization by first splitting on semicolons, then on equals signs. Each level uses its own context variable, allowing safe nested operation. The outer loop splits key-value pairs, while the inner loop separates keys from values. This pattern is common in configuration file parsing. The separate context variables prevent interference between tokenization levels.
Error Handling with strtok_s
This example shows proper error handling with strtok_s
.
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> #include <errno.h> int main() { char *str = NULL; // Invalid input char *token; char *context = NULL; const char *delim = ","; token = strtok_s(str, delim, &context); if (token == NULL && errno != 0) { perror("strtok_s failed"); return 1; } while (token != NULL) { printf("Token: %s\n", token); token = strtok_s(NULL, delim, &context); } return 0; }
strtok_s
sets errno
when encountering invalid
parameters. This example demonstrates checking for errors after a failed call.
When passed a NULL string pointer, strtok_s
returns NULL and sets
errno
to EINVAL. Always check both the return value and
errno
for robust error handling. This is a key advantage over
strtok
, which provides no error reporting mechanism.
Best Practices for Using strtok_s
- Always use separate context variables: For nested or parallel tokenization.
- Check for errors: Verify both return value and errno after each call.
- Prefer over strtok: Use strtok_s in all new code for thread safety.
- Don't modify the string during tokenization: This can lead to undefined behavior.
- Handle empty tokens appropriately: Decide if you need to detect or skip them.
Source
This tutorial has explored the strtok_s
function, from basic usage
to advanced scenarios. As the safer alternative to strtok
, it
should be your first choice for string tokenization in modern C programming.
Author
List C Standard Library.