To search for a specific character in a string we could write a counting loop and look at each character until we find the one we want. But this kind of fundamental task is the kind of thing library functions are good for. string objects provide a find function that finds the first occurrence of a char or string within a string. If you look it up, you will find multiple declarations:
The first one takes a string as a parameter, and the second one takes a character. Both have an optional second parameter pos, which sets a start point for the search. (Recall that the = 0 is the default value, making that parameter optional. See Section 5.9.). Thus yString.find('e',
10) says “find the first ’e’ in myString at or after index 10” while myString.find('e') means “start from 0”. Both functions return the index where they find item being searched from. Because they are returning a location in a string, they return that value as a size_t and not as an int.
A common mistake is to write myString.find('e', 2) in an attempt to find the second e. That actually says “find the first e that is at or after index 2.” The only way to find() the second occurrence of something is to find it once, and then call find again starting at the index 1 past where the first copy was found. As done to find the second "se" in the sample above.
If you try to find() something that is not there, the find function needs to return a value to you that indicates “not found”. That value can’t be 0, as that is a valid location. So the value it returns is the largest possible size_t. This is find()’s way of saying “I searched until the end and did not find what I was looking for”. Rather than try to memorize the value (which can be different on different platforms!), there is a constant that defines this value: string::npos. (Think of string::npos as meaning “npos which is a part of string”. npos is short for “no position” or “null position”.)
If you store attempt to store string::npos to an int, it will have the value -1. This is because string::npos is the binary value 111111...1. That value as a signed int is -1.
In many programming languages, a failed find() returns -1. And that is sort of true in C++. If you cast the returned value into an int it becomes -1. But it isn’t accurate to say that it returns -1. If you try to write something like if (s.find('x') == -1) the compiler will give a warning about comparing the signed (-1) and unsigned (string::npos) values.