C strstr function
last modified April 8, 2025
String operations are fundamental in C programming, and strstr
is a
key function for finding substrings. This tutorial covers strstr
in
depth, including its syntax, usage, and potential pitfalls. We'll explore
practical examples and discuss safer alternatives for critical applications.
Understanding strstr
helps efficiently search strings while
maintaining program safety and reliability.
What Is strstr?
The strstr
function locates the first occurrence of a substring in
a string. It's declared in string.h
and takes two parameters: the
haystack string and needle substring. strstr
returns a pointer to
the found substring or NULL if not found. For security-critical code, consider
bounds-checked alternatives or validate inputs carefully.
Basic strstr Usage
This example demonstrates finding a substring using strstr
.
#include <stdio.h> #include <string.h> int main() { const char *text = "The quick brown fox jumps over the lazy dog"; const char *sub = "fox"; char *result = strstr(text, sub); if (result != NULL) { printf("Found '%s' at position: %ld\n", sub, result - text); } else { printf("'%s' not found\n", sub); } return 0; }
Here, strstr
searches for "fox" in the sample text. The function
returns a pointer to the first character of the found substring. We calculate the
position by subtracting the text pointer from the result pointer. This is a
simple, efficient way to find substrings in C strings. Always check for NULL
return values.
Case-Insensitive Search
This example shows how to implement case-insensitive search using strstr
.
#include <stdio.h> #include <string.h> #include <ctype.h> char* stristr(const char *haystack, const char *needle) { do { const char *h = haystack; const char *n = needle; while (tolower(*h) == tolower(*n) && *n) { h++; n++; } if (*n == 0) { return (char*)haystack; } } while (*haystack++); return NULL; } int main() { const char *text = "C Programming Language"; const char *sub = "PROGRAMMING"; char *result = stristr(text, sub); if (result) { printf("Found '%s' at position: %ld\n", sub, result - text); } else { printf("'%s' not found\n", sub); } return 0; }
This implements a case-insensitive version of strstr
called
stristr
. It converts characters to lowercase before comparison.
The function follows the same pattern as strstr
but with case
ignored. Note that this is not part of standard C library. For production code,
consider more efficient algorithms like Boyer-Moore for large texts.
Finding Multiple Occurrences
This example demonstrates finding all occurrences of a substring.
#include <stdio.h> #include <string.h> int main() { const char *text = "apple orange apple banana apple"; const char *sub = "apple"; const char *ptr = text; int count = 0; while ((ptr = strstr(ptr, sub)) { printf("Found '%s' at position: %ld\n", sub, ptr - text); ptr += strlen(sub); count++; } printf("Total occurrences: %d\n", count); return 0; }
This code finds all occurrences of "apple" in the text. After each find, it
advances the search pointer past the found substring. The loop continues until
strstr
returns NULL. This technique is useful for counting or
processing all matches in a string. Be careful not to create infinite loops with
zero-length substrings.
Extracting Text Between Delimiters
This example shows how to extract text between delimiters using strstr
.
#include <stdio.h> #include <string.h> int main() { const char *text = "Data: [important] and [secret]"; const char *start_delim = "["; const char *end_delim = "]"; const char *start = text; const char *end; while ((start = strstr(start, start_delim))) { start += strlen(start_delim); end = strstr(start, end_delim); if (!end) break; int length = end - start; char extracted[256]; strncpy(extracted, start, length); extracted[length] = '\0'; printf("Extracted: %s\n", extracted); start = end + strlen(end_delim); } return 0; }
This code extracts text between square brackets. It first finds the start delimiter, then looks for the end delimiter. The length between them is calculated and the substring is copied to a buffer. This pattern is useful for parsing structured text. Always ensure your buffer is large enough for the extracted content.
Safe String Search Considerations
This example demonstrates safer string search with length checking.
#include <stdio.h> #include <string.h> char* safe_strstr(const char *haystack, size_t haystack_len, const char *needle, size_t needle_len) { if (!haystack || !needle || needle_len == 0 || haystack_len < needle_len) { return NULL; } for (size_t i = 0; i <= haystack_len - needle_len; i++) { if (strncmp(haystack + i, needle, needle_len) == 0) { return (char*)(haystack + i); } } return NULL; } int main() { char buffer[256] = "Safe string handling is important"; char search[] = "string"; char *result = safe_strstr(buffer, sizeof(buffer), search, strlen(search)); if (result) { printf("Found '%s' at position: %ld\n", search, result - buffer); } else { printf("'%s' not found\n", search); } return 0; }
This implements a safer version of strstr
that includes length
checks. It prevents potential buffer overflows by knowing the maximum lengths.
The function returns NULL for invalid inputs or when the needle is larger than
the haystack. For security-critical applications, such bounds checking is
essential. This approach is more robust than standard strstr
.
Best Practices for Using strstr
- Check for NULL returns: Always verify if the substring was found.
- Validate inputs: Ensure strings are properly null-terminated.
- Consider case sensitivity: Use case-insensitive versions when needed.
- Watch for empty strings: Searching for "" returns the original string.
- Use bounds checking: Implement length checks for security-critical code.
Source
This tutorial has explored the strstr
function, from basic usage to
advanced considerations. While powerful, always use string operations carefully
to prevent security vulnerabilities and undefined behavior in your programs.
Author
List C Standard Library.