string find function help

I am trying to learn all the member functions for string and I am having a hard time making a program that can find all the words that i want to find. It finds what i want once but wont do it twice, and i'm a bit stumped.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void FindWord()
{
    string str = "This is a string of words to search with the search function";

    cout << str << endl;

    cout << "\nEnter a word to find from the string above" << endl;

    string strToFind;

    getline(cin, strToFind);

    string::iterator it = str.begin();

    string compare = strToFind;

    size_t pos = str.find(strToFind);

    while(it != str.end())
    {
        str.find(strToFind);

        if(compare == strToFind)
        {
            cout << "Found \"" << strToFind << "\"" << " at position " << pos << endl;
            break;
        }
        else
        {
            cout << "Did not find \"" << strToFind << "\"" << endl;
            break;
        }
        *it++;
    }
}
Last edited on
Your way to use the function is quite different from the example in the documentation: http://www.cplusplus.com/reference/string/string/find/
ok im really stuck, I have been trying all this time to get it to work and still cant. Idk why.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void FindWord()
{
    ClearInput();
    
    string str = "This is a string of words to search with the search function. It is a lot of words.";

    cout << str << endl;

    cout << "\nEnter a word to find from the string above" << endl;

    string strToFind;

    getline(cin, strToFind);

    size_t pos = str.find(strToFind);

    int timesFound = 0;

    string compare = strToFind;

    while(compare == strToFind)
    {
        if(pos != string::npos && str.find(strToFind, pos + 1))
        {
            cout << "found" << endl;
            cout << ++timesFound << endl;
        }
    }
}
Last edited on
Do you understand what string.find() returns when the find fails? Hint it doesn't return 0.

Now look at this snippet:
1
2
3
4
5
6
7
8
    while(compare == strToFind)
    {
        if(pos != string::npos && str.find(strToFind, pos + 1))
        {
            cout << "found" << endl;
            cout << ++timesFound << endl;
        }
    }

When will this loop end, if compare == strToFind at the beginning of the loop?



I dont know what it returns im very confused.

"When will this loop end, if compare == strToFind at the beginning of the loop"

Yeah, it will go on forever, i was just flailing trying to figure something out.
I dont know what it returns

Then you really must read the documentation. Follow the link in my previous post.
ah, npos is returned.
So something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void FindWord()
{
    string str = "This is a string of words to search with the search function. It is a lot of words.";
    cout << str << endl;

    cout << "\nEnter a word to find from the string above" << endl;

    string strToFind;

    getline(cin, strToFind);

    string::size_type pos = 0;

    int instances = 0;

    string compare = strToFind;

    while((pos = str.find(strToFind, pos)) != string::npos)
    {
        instances++;
        pos += strToFind.size();
    }

    cout << "There are " << instances << " instances of the word " << strToFind << endl;
}
I dont quite fully understand this line:

pos = str.find(strToFind, pos)) != string::npos

I found that code in some old project i had when i first started.

what is it saying?

if pos equals strToFind, position equals current pos and not new pos?
The second parameter of find (pos) tells the function where to start the search. Line 21 ensures that it starts after the last found string.

If you don't provide the pos parameter it always starts from 0 and hence will always find the same string at the same position.
Ah i see but whqat about:

pos = str.find(strToFind, pos))

What does setting str.find(strToFind, pos)) equal to pos do? reset it when it finds a word?
It is not 'equal to'. It assigns the position/index where strToFind is found within str.

If strToFind couldn't be found pos contains string::npos.
oh, i meant assigns sorry. So it does that so it wont go back to the beginning of str?

So the first pos: pos = stores where in the string it found the word, and the second pos gets the location from the first pos so it will continue from that point in the string and not start from the beginning, correct?
correct for both.
The parentheses, the parentheses (and the precedence of operators).
See bottom of http://www.cplusplus.com/doc/tutorial/operators/

This contains two operators: ( pos = str.find(strToFind, pos) ) != string::npos
It is similar to: ( foo = bar ) != gaz

Equality has higher precedence than assignment, but the parentheses change the evaluation order. Thus, the assignment is evaluated first.

One has to evaluate both operands before one can evaluate binary operator (the boolean && and || operators are exceptions). In case of your assignment, the call str.find( strToFind, pos ) is evaluated. It returns a temporary unnamed value.
Then that temporary value is assigned to pos.

Assignment operator does return a value too. That is why you can write:
1
2
3
4
5
6
7
8
9
10
11
a = 42;
b = a;
c = b;

// or

c = b = a = 42;

// which is actually

c = ( b = (a = 42) );

Therefore, these are equivalent:
1
2
3
4
5
6
7
8
9
10
foo = bar;
if ( foo != gaz ) ...

// and

if ( (foo = bar) != gaz ) ...

// and

if ( gaz != (foo = bar) ) ...

Thus, it is the return value of call to string::find that is compared with string::npos. The value just happens to be stored in pos too.

That alone could lead to infinite loop. That is why the loop's body contains pos += strToFind.size();. That ensures (unless strToFind is empty) that the next call to string::find will not return the same position.

One could be a little less confusing:
1
2
3
4
5
6
string::size_type from = 0;
string::size_type match = string::npos;
while ( string::npos != ( match = str.find( strToFind, from ) ) ) {
  // code that uses the match
  from = match + strToFind.size();
}
Topic archived. No new replies allowed.