Learn safe string tokenization in C with this comprehensive strtok_s tutorial. Explore usage, practical examples, and safer alternatives for string operations.
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.
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.
This example demonstrates basic string tokenization using strtok_s.
basic_tokenize.c
#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.
strtok_s can handle multiple delimiter characters, as shown here.
multi_delim.c
#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.
This example demonstrates how strtok_s handles consecutive delimiters.
empty_tokens.c
#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.
This example shows how to use strtok_s in nested tokenization.
nested_tokenize.c
#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.
This example shows proper error handling with strtok_s.
error_handling.c
#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.
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.
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.
My name is Jan Bodnar, and I’m a dedicated programmer with a deep passion for coding. Since 2007, I’ve been sharing my expertise through over 1,400 articles and 8 e-books. With more than a decade of teaching experience, I strive to make programming accessible and engaging.
List C Standard Library.