Question
I have a variable of type std::string, and I want to check whether it contains another std::string. How can I do this in C++?
Is there a built-in function that lets me test whether the substring exists and gives a true or false result?
Short Answer
By the end of this page, you will understand how to check whether one std::string contains another in C++. You will learn how std::string::find() works, how to convert its result into a boolean check, what std::string::npos means, and how this pattern is used in real programs.
Concept
In C++, the usual way to check whether a string contains another string is to use std::string::find().
find() searches for a substring inside another string and returns:
- the starting index of the first match, or
std::string::nposif no match is found
That means find() does not directly return true or false. Instead, you compare its result with std::string::npos.
if (text.find(word) != std::string::npos) {
// found
}
This matters because searching text is a very common programming task. Real programs often need to:
- check whether a filename contains an extension
- detect whether a message contains a keyword
- validate input formats
- filter logs or API responses
- parse simple text-based data
Understanding find() gives you a basic but powerful tool for working with text in C++.
Mental Model
Think of a string like a long sentence written on paper.
You want to know whether a smaller word appears somewhere inside it.
- The large sentence is your main
std::string - The smaller word or phrase is the substring you are searching for
find()acts like your finger scanning from left to right- If it finds the substring, it tells you the position where it starts
- If it never finds it, it returns a special value:
std::string::npos
So the question is not really "Did I get true or false?" The question is:
- "Did I get a valid position?"
- or "Did I get
npos, meaning not found?"
Syntax and Examples
The basic syntax is:
string.find(substring)
It returns the index of the first match, or std::string::npos if there is no match.
Example: basic contains check
#include <iostream>
#include <string>
int main() {
std::string text = "Hello world";
std::string target = "world";
if (text.find(target) != std::string::npos) {
std::cout << "Found\n";
} else {
std::cout << "Not found\n";
}
return 0;
}
This prints:
Found
Example: search for a literal string
#include <iostream>
#include <string>
int main() {
std::string message = "error: invalid input";
bool hasError = message.find("error") != std::string::npos;
std::cout << std::boolalpha << hasError << '\n';
return 0;
}
Output:
true
Example: substring not found
#include <iostream>
#include <string>
int main() {
std::string text = "banana";
if (text.find("apple") == std::string::npos) {
std::cout << "Substring not found\n";
}
return 0;
}
Important note
find() is case-sensitive.
std::string text = "Hello";
text.find("hello") != std::string::npos; // false
Because H and h are different characters.
Step by Step Execution
Consider this code:
#include <iostream>
#include <string>
int main() {
std::string text = "C++ strings are useful";
std::string target = "strings";
std::size_t pos = text.find(target);
if (pos != std::string::npos) {
std::cout << "Found at index: " << pos << '\n';
} else {
std::cout << "Not found\n";
}
return 0;
}
Step by step
-
textstores the full string:C++ strings are useful -
targetstores the substring you want to search for:strings -
text.find(target)searches from the beginning oftext. -
The substring
"strings"starts at index4, soposbecomes4. -
The
ifstatement comparesposwithstd::string::npos. -
Since
4 != std::string::npos, the substring was found. -
The program prints:
Found at index: 4
If it is not found
If target were "arrays", then:
std::size_t pos = text.find("arrays");
pos would be std::string::npos, so the else branch would run.
Real World Use Cases
Checking whether one string contains another appears in many practical situations.
Input validation
if (email.find("@") == std::string::npos) {
std::cout << "Invalid email address\n";
}
Log filtering
if (logLine.find("ERROR") != std::string::npos) {
// process error log
}
File extension checks
if (fileName.find(".txt") != std::string::npos) {
// text file detected
}
Command parsing
if (command.find("--help") != std::string::npos) {
// show help message
}
Content moderation or keyword detection
if (message.find("spam") != std::string::npos) {
// flag message
}
Simple configuration parsing
if (line.find("port=") != std::string::npos) {
// parse port setting
}
Real Codebase Usage
In real codebases, developers often wrap string searching inside cleaner helper functions or use it in validation and filtering logic.
Pattern: convert find() into a boolean helper
#include <string>
bool contains(const std::string& text, const std::string& part) {
return text.find(part) != std::string::npos;
}
This makes calling code easier to read:
if (contains(configLine, "timeout=")) {
// parse timeout value
}
Pattern: guard clause
if (input.find(":") == std::string::npos) {
return false;
}
This is common when validating formats before doing more work.
Pattern: filter records
for (const auto& line : lines) {
if (line.find("WARNING") != std::string::npos) {
std::cout << line << '\n';
}
}
Pattern: simple feature detection
if (userAgent.find("Mobile") != std::string::npos) {
// mobile-specific behavior
}
Pattern: error handling
if (response.find("error") != std::string::npos) {
throw std::runtime_error("Server returned an error");
}
In production code, developers also think about:
- case sensitivity
- whether partial matches are acceptable
- performance when searching many times
- whether a more structured parser would be better than substring checks
Common Mistakes
1. Comparing the result to 0 instead of npos
Broken code:
if (text.find("abc")) {
std::cout << "Found\n";
}
Why this is wrong:
- If the substring is found at index
0, the condition becomes false. find()returns a position, not a boolean.
Correct version:
if (text.find("abc") != std::string::npos) {
std::cout << "Found\n";
}
2. Forgetting that find() is case-sensitive
Broken expectation:
std::string text = "Hello";
bool found = text.find("hello") != std::string::npos; // false
How to avoid it:
- remember uppercase and lowercase are different
- convert both strings to the same case if needed before searching
3. Using the wrong comparison operator
Broken code:
if (text.find(word) == true) {
// wrong
}
Why this is wrong:
find()returns an index, nottrueorfalse- comparing it with
truedoes not mean "found"
Correct version:
if (text.find(word) != std::string::npos) {
// found
}
4. Assuming find() only works with std::string
It can also search for string literals and characters.
text.find("cat");
text.find('c');
5. Not storing the result when you need the position later
Less useful:
if (text.find("id=") != std::string::npos) {
// then search again later
}
Better:
std::size_t pos = text.find("id=");
if (pos != std::string::npos) {
std::cout << "Found at: " << pos << '\n';
}
6. Confusing substring search with exact equality
std::string a = "hello world";
std::string b = "hello";
a == bchecks whether both strings are exactly the samea.find(b) != std::string::nposchecks whetherbappears insidea
Comparisons
| Task | Best choice | What it does |
|---|---|---|
| Check exact equality | == | Tests whether two strings are exactly identical |
| Check whether a string contains another string | find() | Searches for a substring and returns its position |
| Check whether a string starts with something | rfind(..., 0) or starts_with() in newer C++ | Tests prefix matching |
| Check whether a string ends with something | ends_with() in newer C++ | Tests suffix matching |
| Search with complex patterns | regex | Useful for pattern matching, but heavier |
== vs find()
std::string text = "hello world";
bool same = (text == "world"); // false
bool contains = (text.find("world") != std::string::npos); // true
find() vs regex
- Use
find()when you want a simple substring search - Use regex only when you need pattern rules like digits, optional parts, or repetition
Modern C++ note
In newer C++ standards, some libraries provide more direct helpers such as contains(), but find() remains the classic and widely supported approach.
If you need broad compatibility, find() is usually the safest choice.
Cheat Sheet
// Basic contains check
text.find(part) != std::string::npos
Rules
find()returns the starting index of the first match- If nothing is found, it returns
std::string::npos find()is case-sensitivefind()does not returnbool
Common patterns
if (text.find("abc") != std::string::npos) {
// found
}
if (text.find("abc") == std::string::npos) {
// not found
}
std::size_t pos = text.find("abc");
if (pos != std::string::npos) {
std::cout << pos << '\n';
}
Search types
text.find("word"); // substring
text.find('x'); // single character
Common mistake to avoid
if (text.find("abc")) // wrong
Use:
if (text.find("abc") != std::string::npos) // correct
Edge cases
- If the substring is at index
0, it is still found - An empty substring is considered found at position
0 - Search is case-sensitive unless you normalize case yourself
FAQ
How do I check if a std::string contains another string in C++?
Use find() and compare the result to std::string::npos:
if (text.find(part) != std::string::npos) {
// found
}
Does std::string::find() return true or false?
No. It returns the index where the substring starts, or std::string::npos if it is not found.
What is std::string::npos in C++?
It is a special constant meaning "no position" or "not found".
Is find() case-sensitive?
Yes. For example, "Hello" and "hello" are treated as different strings.
Can I search for a character instead of a string?
Yes.
text.find('a');
What happens if I search for an empty string?
It is considered found at position 0.
Is there a built-in contains() function in C++?
In many codebases, find() is the standard portable approach. Some newer environments may offer contains(), but find() is the classic solution and works widely.
Should I use == or find()?
- Use
==when checking for exact equality - Use
find()when checking whether one string appears inside another
Mini Project
Description
Build a small C++ program that checks log messages for important keywords. This demonstrates how substring searching is used in tools that inspect text and react to its content.
Goal
Create a program that scans a list of log messages and labels each message based on whether it contains words like ERROR or WARNING.
Requirements
- Store several log messages in a collection
- Check each message for the substrings
ERRORandWARNING - Print a label for each message based on what it contains
- Use
std::string::find()for the checks
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.