C String strstr() Function

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
<string.h>

What You’ll Learn

The strstr() function locates the first occurrence of a substring inside a larger C string. It is one of the most common search tools in <string.h> when you need to find words, file extensions, or any multi-character pattern.

01

Find sub

First match.

02

char*

Pointer.

03

NULL

Not found.

04

Index

p - str.

05

Case

Sensitive.

06

vs strchr

One char.

Definition and Usage

strstr searches a haystack string for a needle substring. When the needle appears, the function returns a pointer to the first character of the match inside the haystack—not a copy of the substring.

For example, searching "simple" in "This is a simple example." returns a pointer to the 's' in "simple example."

💡
Beginner Tip

strchr finds a single character; strstr finds a whole substring. Always test for NULL before using the returned pointer—printing or dereferencing NULL crashes your program.

📝 Syntax

Standard C declaration:

C
char *strstr(const char *haystack, const char *needle);

Parameters

  • haystack — null-terminated string to search in.
  • needle — null-terminated substring to find.

Return Value

  • Pointer to the first byte of the first occurrence of needle in haystack.
  • NULL if needle is not found.
  • If needle is empty (""), returns haystack.

Header

  • #include <string.h>

⚡ Quick Reference

haystackneedleResult
"This is a simple example.""simple"ptr to "simple example."
"hello world""world"ptr to "world"
"abc""xyz"NULL
"abc"""ptr to "abc"
Find sub
strstr(hay, needle)

First match

Check found
if (p != NULL)

Safe use

Get index
p - haystack

Zero-based

One char
strchr(hay, 'x')

Single byte

Examples Gallery

Compile with gcc strstr.c -std=c11 -o strstr. Every example checks for NULL before using the result.

📚 Getting Started

Locate a substring and print the remainder of the haystack from the match.

Example 1 — Find a Substring

Search for "simple" inside a sentence, as in the reference tutorial.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *haystack = "This is a simple example.";
    const char *needle   = "simple";

    char *result = strstr(haystack, needle);

    if (result != NULL) {
        printf("Substring found: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

How It Works

result points into haystack at the 's' of "simple". Printing result shows everything from that position to the end.

Example 2 — Handle a Missing Substring

Demonstrate the NULL return when the needle is absent.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *text = "CodeToFun tutorials";
    const char *word = "Python";

    char *hit = strstr(text, word);

    if (hit) {
        printf("Found at: %s\n", hit);
    } else {
        printf("'%s' was not found in '%s'.\n", word, text);
    }

    return 0;
}

How It Works

No match means hit is NULL. The if (hit) branch skips printing the pointer, avoiding undefined behavior.

📈 Practical Patterns

Index calculation, repeated search, and comparison with single-character lookup.

Example 3 — Compute the Match Index

Turn the returned pointer into a zero-based position.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *line = "user=admin;role=editor";
    const char *key  = "role=";

    char *p = strstr(line, key);

    if (p != NULL) {
        size_t index = (size_t)(p - line);
        printf("Found '%s' at index %zu\n", key, index);
        printf("Value starts at: %s\n", p + strlen(key));
    }

    return 0;
}

How It Works

Pointer subtraction works because both pointers refer to the same line array. Adding strlen(key) skips past the key to read the value.

Example 4 — Find Every Occurrence

Advance past each match to locate repeated substrings.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *text   = "foo bar foo baz foo";
    const char *needle = "foo";
    const char *cursor = text;
    int count = 0;

    while ((cursor = strstr(cursor, needle)) != NULL) {
        printf("Match %d at index %td: %s\n",
               ++count, cursor - text, cursor);
        cursor++;  /* move past current 'f' to find overlapping? no - next char */
    }

    printf("Total: %d\n", count);

    return 0;
}

How It Works

After each hit, increment cursor by one (or by strlen(needle) to skip non-overlapping matches). The loop stops when strstr returns NULL.

Example 5 — strstr() vs strrchr()

Find a file extension with strstr and the filename start with strrchr.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *path = "/home/user/report.pdf";

    char *ext = strstr(path, ".pdf");
    char *slash = strrchr(path, '/');

    if (ext) {
        printf("Extension match: %s\n", ext);
    }
    if (slash) {
        printf("Filename:        %s\n", slash + 1);
    }

    return 0;
}

How It Works

strstr matches the multi-byte suffix ".pdf". strrchr finds the last '/' so you can isolate the filename. Together they cover common path parsing tasks.

🚀 Common Use Cases

  • Keyword detection — check whether user input contains a command or flag.
  • File extensions — locate ".txt", ".json", or similar suffixes.
  • Config parsing — find "key=" before reading a value.
  • Log filtering — detect error codes or module names inside log lines.
  • Simple replace prep — find a match, then copy or overwrite surrounding text manually.

🧠 How strstr() Works

1

Start at haystack[0]

Try to match needle at the current position.

Init
2

Compare bytes

If needle matches, return pointer here. Otherwise advance one byte in haystack.

Scan
3

End of haystack

If no match before '\0', return NULL.

Fail
=

char* or NULL

Address inside haystack, or no match.

📝 Notes

  • Case-sensitive byte comparison—"ABC" and "abc" do not match.
  • The returned pointer aliases haystack; do not free it separately.
  • Empty needle ("") returns haystack per the C standard.
  • Do not pass NULL for either argument—behavior is undefined.
  • For bounded buffers (not guaranteed null-terminated), prefer memmem on POSIX or manual length-limited search.

⚡ Optimization

Standard library implementations often use efficient algorithms (such as Two-Way search) for long needles. If you call strstr repeatedly on the same haystack, save the result pointer instead of searching again. For very large data or binary blobs, consider specialized search routines with explicit lengths.

Conclusion

strstr() is the standard way to find the first occurrence of a substring in C. Check for NULL, use pointer arithmetic for indices, and combine it with strchr or strrchr when you need single-character delimiters.

Next, explore strpbrk() to locate the first character from a set.

💡 Best Practices

✅ Do

  • Always check if (p != NULL) before use
  • Use p - haystack for zero-based index
  • Advance the search pointer to find later matches
  • Use strchr when searching for one character
  • Include <string.h>

❌ Don’t

  • Dereference or print a NULL result
  • Assume case-insensitive matching
  • Pass non-null-terminated buffers as haystack
  • Confuse return pointer with a newly allocated string
  • Call with NULL arguments

Key Takeaways

Knowledge Unlocked

Five things to remember about strstr()

Use these points when searching for substrings in C.

5
Core concepts
📝 02

NULL Safe

Check result.

Safety
🔢 03

Index

p - hay.

Pointer
📈 04

Multi-byte

Whole sub.

Use case
💬 05

vs strchr

One char.

Compare

❓ Frequently Asked Questions

strstr() searches haystack for the first occurrence of needle (a substring). It returns a pointer to the start of the match inside haystack, or NULL if needle is not found.
char* strstr(const char* haystack, const char* needle); Include <string.h>. haystack is the string to search. needle is the substring to locate.
It returns NULL. Always check the result before dereferencing or printing it.
Yes. strstr() compares bytes exactly. "Hello" and "hello" are different. For case-insensitive search on POSIX systems, strcasestr() may be available as an extension.
If char* p = strstr(haystack, needle) is non-NULL, the zero-based index is (size_t)(p - haystack). Both pointers must refer to the same array.
strstr() returns haystack—the empty string is considered to match at the beginning. This is defined by the C standard.
Did you know?

C++ offers std::string::find, but in C, strstr remains the idiomatic choice for null-terminated strings. On GNU/Linux, strcasestr() provides a case-insensitive variant—it is not part of standard C, so wrap it in #ifdef if you need portable code.

Continue the String Functions Series

Find substrings with strstr(), then locate any character from a set with strpbrk().

Next: strpbrk() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful