C++ Check if String Contains Substring
To check if a string contains a substring in C++, use find: text.find("word") != std::string::npos is true when the substring is present. In C++23 there’s also a cleaner contains() method. Let’s look at both, plus how to do a case-insensitive search.
The Standard Way: find
std::string::find searches for a substring and returns the index where it starts — or the special value std::string::npos if it isn’t there:
#include <iostream>
#include <string>
int main() {
std::string text = "the quick brown fox";
if (text.find("brown") != std::string::npos) {
std::cout << "Found it!\n";
} else {
std::cout << "Not found.\n";
}
return 0;
}
The key is comparing against std::string::npos. Because find returns an index (and index 0 is a valid match at the very start), you must not test it as a simple true/false — always compare with npos.
Getting the Position
The return value of find is useful on its own when you want to know where the match is:
std::string text = "name=Alice";
size_t pos = text.find("=");
if (pos != std::string::npos) {
std::string value = text.substr(pos + 1); // "Alice"
std::cout << value << "\n";
}
Here find locates the =, and substr grabs everything after it. This pairs naturally with splitting and parsing tasks.
The Modern Way: contains (C++23)
C++23 added a contains() method that returns a bool directly, so there’s no npos comparison to remember:
// Requires C++23: compile with g++ -std=c++23
std::string text = "the quick brown fox";
if (text.contains("brown")) {
std::cout << "Found it!\n";
}
This is the most readable option when your compiler supports it. If you’re on an older toolchain, the find approach above does exactly the same job.
Case-Insensitive Search
find is case-sensitive, so "Brown" won’t match "brown". For a case-insensitive check, convert both strings to lowercase first:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string toLower(std::string s) {
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return std::tolower(c); });
return s;
}
int main() {
std::string text = "The Quick Brown Fox";
bool found = toLower(text).find("brown") != std::string::npos;
std::cout << (found ? "found\n" : "missing\n"); // found
return 0;
}
We lowercase a copy of the text (and your search term, if needed) so the comparison ignores case. Wrapping std::tolower in a lambda with unsigned char avoids a subtle undefined-behavior trap with negative characters.
Quick Reference
| Goal | Code |
|---|---|
| Does it contain X? | s.find("X") != std::string::npos |
| C++23 shortcut | s.contains("X") |
| Where is X? | size_t pos = s.find("X"); |
| Ignore case | lowercase both, then find |
Related Articles
- C++ String Handling — find, substr, replace, and more
- C++ Split String — break a string into pieces
- C++ stringstream — stream-based parsing
- C++ String to int — convert found text to numbers
Take Your C++ Further
If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.