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.
Fundamentals
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.
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.
Cheat Sheet
⚡ Quick Reference
String
Call
Result
"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
Hands-On
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;
}
📤 Output:
Substring found at position: 7
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;
}
📤 Output:
At sign index: 4
No hash symbol in email.
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;
}
📤 Output:
First 'na' at: 2
Second 'na' at: 4
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;
}
📤 Output:
Found at index 0
Found at index 8
Found at index 16
Total matches: 3
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.
URL has /cpp: true
File is PDF: true
File is TXT: false
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.
Applications
🚀 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.
Important
📝 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.
Performance
⚡ 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.
Wrap Up
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.
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)
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about find()
Use these points whenever you search inside C++ strings.
5
Core concepts
🔍01
Search Member
Call on std::string.
Basics
🔢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.