Skip to main content

Section 9.9 find in strings

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:
size_t find (const string& str, size_t pos = 0) const;
size_t find (char c, size_t pos = 0) const;
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.6.). Thus `myString.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.
The example below demonstrates their use on the string She sells sea shells. For reference, here are the indices for the characters of that string:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
S h e s e l l s s e a s h e l l s
Listing 9.9.1.
Some things to note:
  • The first e is at index 2 (in โ€œSheโ€)
  • The first ell starts at index 5
  • The first se starts at index 4. That is the value stored into seIndex
  • myString.find("se", seIndex + 1) starts from index 5. Starting at that point, the next occurrence of "se" is at index 10.

Warning 9.9.1.

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โ€.)
Here is an example of trying to find q in our string:
Listing 9.9.2.
You can try changing the target to some character to see the behavior when the value is found.

Insight 9.9.2.

This is how you check if a string contains some other string. Do a find() and see if the value is != string::npos.

Note 9.9.3.

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.

Checkpoint 9.9.1.

Checkpoint 9.9.2.

Checkpoint 9.9.3.

Construct a block of code that correctly finds and prints where the third i is in the string.
You have attempted of activities on this page.