What Is std::string::npos in C++?
std::string::npos is a constant that means "no position". The find functions return it when the text you searched for is not there.
It is a static member constant of std::basic_string. Its type is std::string::size_type, which is an unsigned integer type. For a normal std::string that type is std::size_t.
The standard defines the value as size_type(-1). Because the type is unsigned, that wraps to the largest value the type can hold. On a 64 bit build that is 18446744073709551615.
You should never write that number yourself. Write std::string::npos and let the compiler pick the right value.
#include <iostream> #include <string> int main() { std::string s = "hello world"; std::string::size_type pos = s.find("world"); if (pos != std::string::npos) { std::cout << "found at " << pos << "\n"; // found at 6 } else { std::cout << "not found\n"; } if (s.find("zebra") == std::string::npos) { std::cout << "zebra is not in the string\n"; } return 0; }
The output is found at 6 and then zebra is not in the string.
The functions that return npos
Every search member of std::string reports failure the same way.
| Function | Returns npos when |
|---|---|
find | The substring or character is not present |
rfind | No match exists searching backward |
find_first_of | None of the given characters appear |
find_last_of | None of the given characters appear |
find_first_not_of | Every character is one of the given ones |
find_last_not_of | Every character is one of the given ones |
std::string_view and std::wstring follow the same rule. Each has its own npos with the same meaning.
npos also means "to the end of the string"
This second meaning surprises many people. Several functions take a length argument, and npos as that length means "take everything that is left".
std::string s = "hello world"; std::string tail = s.substr(6); // length defaults to npos std::string same = s.substr(6, std::string::npos); // tail == same == "world"
substr, erase, replace, compare and insert all read npos this way. So the constant has one value and two jobs. It is a failure signal when returned, and a "rest of the string" marker when passed in.
One trap sits here. s.substr(pos) throws std::out_of_range if pos is greater than the size. So check the result of find before you pass it to substr.
The common mistake
size_type is unsigned, so a "not found" result is a huge positive number, never a negative one.
std::string s = "hello world"; // Wrong: an unsigned value is always >= 0, so this is always true. if (s.find("zebra") >= 0) { /* runs even though zebra is absent */ } // Wrong: a match at position 0 is valid, but 0 is false. if (s.find("hello")) { /* skipped, though hello is at index 0 */ } // Right: if (s.find("zebra") != std::string::npos) { /* only when found */ }
Two more habits cause bugs. Do not store the result in an int, because the value does not fit and the conversion is not portable. Do not compare against a literal -1, because that hides the type and breaks on other string types.
The safe pattern is short. Store the result in std::string::size_type or use auto. Then compare with std::string::npos.
How to Prepare
- Memorize one line.
if (s.find(x) != std::string::npos)is the only correct shape you need in an interview. - Use
autofor the result. It gives you the right unsigned type without naming it, so the comparison stays honest. - Practice string questions in C++. Substring search, palindromes and anagrams all use
findand index arithmetic. Grokking the Coding Interview groups these into repeatable patterns. - Know the underlying structure. Strings are contiguous arrays, which explains why
findis a linear scan. Grokking Data Structures for Coding Interviews covers that model. - Compare across languages. Other languages return
-1instead. See how string reversal differs in C and C# and the difference between String and string in C#. - Say the complexity.
findis O(n times m) in the worst case for a naive scan. Interviewers expect you to state that.

GET YOUR FREE
Coding Questions Catalog

$99

$197

$72