C++ String find() Function

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
std::string

What You’ll Learn

The find() member of std::string locates a substring inside text and returns its starting index. It is the standard C++ way to answer “Is this word in the string?” and “Where does it start?”—essential for parsing URLs, validating input, and searching log lines.

01

Substring Search

Find text inside text.

02

Returns size_t

Zero-based index.

03

npos on Failure

Special not-found value.

04

Start Position

Optional pos param.

05

Case-Sensitive

Exact character match.

06

vs rfind()

First vs last match.

Definition and Usage

In C++, std::string is the modern class for text. Its find() method searches the calling string for another string (or a single character) and reports where the match begins. Indexing is zero-based: the first character is at position 0.

If the substring appears multiple times, find() returns only the first occurrence unless you call it again with an updated start position. When nothing matches, the result is std::string::npos—always compare against that constant instead of guessing a numeric value.

💡
Beginner Tip

Think of find() like searching a sentence for a word. It tells you the starting letter position, or it tells you “not found” via npos. It does not remove or replace text—it only searches.

📝 Syntax

The most common overloads declared in <string>:

C++
size_t find(const std::string& str, size_t pos = 0) const;
size_t find(const char* s, size_t pos, size_t count) const;
size_t find(const char* s, size_t pos = 0) const;
size_t find(char ch, size_t pos = 0) const;

Parameters

  • str / s / ch — the substring, C-string, or single character to search for.
  • pos — optional index where the search begins (default 0, the start of the string).
  • count — (C-string overload) maximum number of characters from s to compare.

Return Value

Returns the index of the first character of the first match. Returns std::string::npos if the substring is not found.

⚡ Quick Reference

StringCallResult
"Hello, C++!"find("C++")7
"Hello, C++!"find("Java")std::string::npos
"banana"find("na")2 (first match)
"banana"find("na", 3)4 (search from index 3)
"file.txt"find('.')4
Basic
text.find("key")

Find substring

Contains
text.find("x") != npos

True if present

From index
text.find("a", 5)

Skip early chars

One char
text.find('@')

Find a symbol

Examples Gallery

Compile with any C++11+ compiler (for example g++ find.cpp -std=c++17 -o find). Each example builds practical search skills step by step.

📚 Getting Started

Locate a substring and print its index.

Example 1 — Basic find() Usage

Search for "C++" inside "Hello, C++!". Count from 0: H(0)… space(6), C(7).

C++
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, C++!";

    size_t position = text.find("C++");

    if (position != std::string::npos) {
        std::cout << "Substring found at position: "
                  << position << std::endl;
    } else {
        std::cout << "Substring not found." << std::endl;
    }

    return 0;
}

How It Works

find("C++") scans left to right and returns the index where the match begins. Comparing with std::string::npos confirms success before you use the index.

Example 2 — Handling a Missing Substring

When the search text is absent, find() returns npos—never assume zero means “not found.”

C++
#include <iostream>
#include <string>

int main() {
    std::string email = "user@example.com";

    size_t at = email.find("@");
    size_t hash = email.find("#");

    std::cout << "At sign index: " << at << std::endl;

    if (hash == std::string::npos) {
        std::cout << "No hash symbol in email." << std::endl;
    }

    return 0;
}

How It Works

@ is found at index 4. # is missing, so find returns npos and the program prints a clear message instead of using an invalid index.

📈 Practical Patterns

Start position, repeated search, and validation helpers.

Example 3 — Search from a Start Position

Pass a second argument to skip characters you have already checked.

C++
#include <iostream>
#include <string>

int main() {
    std::string word = "banana";

    size_t first = word.find("na");
    size_t second = word.find("na", first + 1);

    std::cout << "First 'na' at: " << first << std::endl;
    std::cout << "Second 'na' at: " << second << std::endl;

    return 0;
}

How It Works

The first call finds "na" at index 2. The second call starts at index 3 (first + 1), so it discovers the next match at 4 instead of returning 2 again.

Example 4 — Find All Occurrences in a Loop

Repeat find() with an advancing start index to locate every match.

C++
#include <iostream>
#include <string>

int main() {
    std::string data = "one two one three one";
    std::string target = "one";
    size_t pos = 0;
    int count = 0;

    while ((pos = data.find(target, pos)) != std::string::npos) {
        std::cout << "Found at index " << pos << std::endl;
        count++;
        pos += target.length();
    }

    std::cout << "Total matches: " << count << std::endl;
    return 0;
}

How It Works

Each iteration records a match and moves pos forward by the length of the target so overlapping false positives are avoided. The loop stops when find returns npos.

Example 5 — Contains-Style Validation

Use find() as a yes/no check before parsing a URL or file name.

C++
#include <iostream>
#include <string>

bool contains(const std::string& haystack, const std::string& needle) {
    return haystack.find(needle) != std::string::npos;
}

int main() {
    std::string url  = "https://codetofun.com/cpp/string/function/find";
    std::string file = "report.pdf";

    std::cout << std::boolalpha;
    std::cout << "URL has /cpp: " << contains(url, "/cpp") << std::endl;
    std::cout << "File is PDF: " << contains(file, ".pdf") << std::endl;
    std::cout << "File is TXT: " << contains(file, ".txt") << std::endl;

    return 0;
}

How It Works

A tiny contains helper wraps the find != npos idiom. C++23 adds std::string::contains(), but this pattern works in C++98 through C++20 and remains very common in existing codebases.

🚀 Common Use Cases

  • URL and path parsing — locate "/", "?", or domain segments before splitting.
  • File extension checks — confirm ".cpp", ".txt", or ".json" appears in a file name.
  • Input validation — verify an email contains "@" or a command includes a required flag.
  • Log analysis — search large text buffers for error codes or keywords.
  • Token extraction — combine find() with substr() to slice text between delimiters.

🧠 How find() Works

1

You call find(target, pos)

The string receives the needle (substring or char) and an optional starting index.

Input
2

Characters are compared

The implementation scans forward from pos, comparing the target sequence at each offset.

Search
3

Match or exhaust text

On success, the starting index is returned. If no slot matches, the function returns npos.

Result
=

Index or npos

Use the index with substr(), loops, or validation logic—or branch when text is absent.

📝 Notes

  • The search is case-sensitive"Java" and "java" are different.
  • Always compare results with std::string::npos; do not rely on -1 (wrong type and value).
  • find() returns the first match only; use a loop or rfind() for other needs.
  • Include <string> and use the std::string class—not C-style char* search functions unless you intentionally work with C strings.
  • Passing a C-string to find requires a null-terminated const char*; avoid unterminated buffers.

⚡ Optimization

For typical beginner and application strings, find() is fast enough and well optimized in standard libraries. For very large texts searched repeatedly, consider whether you need a specialized algorithm (Boyer–Moore, hash maps, or full-text indexes). Avoid calling find() on the same huge string thousands of times inside tight loops without caching results or restructuring data.

Conclusion

The C++ find() function is a fundamental tool for substring search. It tells you where text appears—or clearly signals absence with std::string::npos. Combined with loops and optional start positions, it covers most everyday parsing tasks.

Practice the examples until comparing with npos feels natural, then explore related C string functions like strchr() and strcmp() in this series.

💡 Best Practices

✅ Do

  • Compare with std::string::npos for not-found checks
  • Pass a start index when searching for multiple matches
  • Wrap repeated checks in a small contains() helper
  • Include <string> and prefer std::string
  • Combine with substr() to extract matched regions

❌ Don’t

  • Assume return value 0 means failure (valid match at start)
  • Compare find() results to -1
  • Expect case-insensitive matching by default
  • Forget to advance pos in find-all loops (infinite loop risk)
  • Mix up find() (first match) with rfind() (last match)

Key Takeaways

Knowledge Unlocked

Five things to remember about find()

Use these points whenever you search inside C++ strings.

5
Core concepts
🔢 02

size_t Index

Zero-based position.

Return
03

npos

Means not found.

Safety
📈 04

Start at pos

Find next match.

Pattern
📝 05

Case-Sensitive

Exact text match.

Rule

❓ Frequently Asked Questions

find() searches a std::string for a substring (or single character) and returns the zero-based index of the first match. If the text is not found, it returns std::string::npos—a special size_t value meaning "not found."
Call it on a string object: text.find("needle"). Common forms include find(str), find(str, pos) to start at a position, find(ch) for one character, and find(str, pos, count) for a limited-length search.
It returns size_t—the index of the first character of the first match. On failure it returns std::string::npos. Always compare with npos (or use pos != string::npos) instead of treating the result as a boolean directly.
Yes. find() matches exact letter case. To search without caring about case, normalize both strings to lowercase first, or use std::search with a custom comparison (C++20 also offers std::ranges with case-insensitive helpers in some libraries).
find() locates the first (leftmost) occurrence. rfind() searches from the end and returns the last (rightmost) match. Use find() for forward search; use rfind() for file extensions, trailing paths, or the final delimiter in a string.
Use if (text.find("Java") != std::string::npos) { /* found */ }. There is no separate contains() member in C++17 and earlier; C++23 adds std::string::contains(), but find() works in all common standards.
Did you know?

std::string::npos is the largest possible size_t value on your platform. It is defined in the std::string class so you can always write if (s.find("x") == std::string::npos) without magic numbers.

Keep Building C++ String Skills

Master substring search with find(), then continue to C-style string functions like strcat() and strcmp().

Next: strcat() →

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