Finding letters in a string

Pages: 12
Hello guys, i'm new and I'm trying to compile a program that sees wether a user-inputted string contains the letter 'i' inside, using the find_first_of() function. This is what I have done so far:
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
#include <iostream>
#include<string>

using namespace std;

int main (int argc, char *argv[])
{
  int sentence;
  int counter;
  char string[10000];
  cout<<"How many sentences would you like to check?" <<endl;
  cin>>sentence;
  for(counter=1;counter<=sentence;counter++)
  {
        cout<<"Enter a sentence that you would like to check for the word 'idiot'"<<endl;
        cin>>string;
        std::string(string);
        unsigned found=string.find_first_of('i',0);
        found=string.find_first_of('i',found++);
        if(string[!found])
        {
            cout<<"An 'i' is present";
        }
        else
        {
            cout<<"An 'i' is not present";
        }
  }
  
  
  return 0;
}
Line 10: name conflict. You use "string" as name for a variable, but namespace std has typename "string".

Line 13: the convention is to loop [0..count[, not [1..count].

Line 16 reads only one word. See the reference documentation for istream >> and skipws. Use getline for sentences and read directly to a std::string.

Line 17 does nothing. Well, it creates a nameless std::string, but that is never used anywhere.
Line 18: 'string' is still a char[], and the return type of find_first_of is different.

Line 19 and 20: Return value of string::find_first_of is string::npos, if nothing was found. You should check for that before using the found as index.
Line 19: found++ is post-increment. You would need pre-increment here.
Line 20: "not" only flips between 0 and non-0.

Overall, your routine seems to look for two 'i' from input, but the output talks of only one.string::find

find_first_of( list ) does "find from string any character that is on the list". As long as you look for only "i", the string::find is sufficient.


Did you try to compile your program? Did the compiler report warnings or errors?
Last edited on
Thanks for your reply, I am using Eclipse and on line 18, and 19 it says that method find_first_of could not be resolved.

I am actually going to be trying to make the program look for the characters 'i' 'd' 'o' 't'

So far when I run it, it just says that an "i" is not present, even if I input a sentence that has an "i" inside.

Also, only having learned programming for a week or two, I'm not sure how to return str::npos based on failure. This is what I've done so far.
#include <iostream>
#include<string>
#include<cstring>
using namespace std;

int main() {
int sentence;
int counter;
std::string str;
cout<<"How many sentences would you like to check?" <<endl;
cin>>sentence;
for(counter=0;counter<=sentence;counter++)
{

getline(std::cin,str);
unsigned found=str.find_first_of("idiot",0);

found=str.find_first_of("idiot",++found);

if(str[found])
{
std::cout<<"There is an 'idiot'. ";
}
else
{
std::cout<<"There isn't an 'idiot'.";
}
}

return 0;
}
Last edited on
Just make a string called idiot and make a loop that compares the two, ie:

for(int n=0;idiot[n]==userinput[n];n++)

or something along those lines. It's more complicated with a sentence but just to give you ideas (you can access string as arrays because, well, they are arrays).

Oh, and you want to put one function in main and have the rest in other functions that that function calls. It doesn't matter now but it's good practice (apparently, I'm noobish as well).
Last edited on
The manual of find_first_of has an example of usage.
http://www.cplusplus.com/reference/string/string/find_first_of/


@agnophilo: Lets assume that idiot and userinput have identical strings. When will your loop stop?

if ( std::string::npos != str.find( "idiot" ) ) std::cout << "bingo\n";
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
#include <iostream>
#include <string>

int main()
{
	while ( true )
	{
		std::cout << "Enter a sentence (<enter> to quit): ";

		std::string s;
		std::getline( std::cin, s );

		if ( s.empty() ) break;

		const char *t = "idiot";

		std::string::size_type n = s.find( t );

		if ( n != std::string::npos )
		{
			std::cout << "There is word \"" << t << "\" in the sentence" << std::endl;
		}
		else
		{
			std::cout << "There is no word \"" << t << "\" in the sentence" << std::endl;
		}

		std::cout << std::endl;
	}
}
"@agnophilo: Lets assume that idiot and userinput have identical strings. When will your loop stop?"

Make it stop once a counter reaches the number of letters in "idiot" or userinput[n] =='N', and reset when the next letter is not a match so that "id is required for training" doesn't set it off (since it has all the letters for idiot in sequence).
Thank you for your replies. The reason i'm using the find_first_of function is beacuse the word idiot has to be found in individual characters within an input. I.E: "i(i) d(d)on't li(i)ke to(o) eat(t)". I was thinking of nesting a couple of "for" loops inside eachother that look for each letter individually. Would that work or would I need to make another variable and multiple functions that are called on in main() that look for each individual letter?
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
36
37
38
39
40
41
42
43
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <utility>
#include <cstring>

int main()
{
	while ( true )
	{
		std::cout << "Enter a sentence (<enter> to quit): ";

		std::string s;
		std::getline( std::cin, s );

		if ( s.empty() ) break;

		const char *idiot = "idiot";

		std::pair<std::string::const_iterator, std::string::const_iterator> 
			p( s.cbegin(), s.cend() );

		bool is_present = std:: all_of( idiot, idiot + std::strlen( idiot ),
                            [&]( char c ) -> bool
                            {
				auto it = std::find( p.first, p.second, c );
				if ( it != p.second ) p.first = std::next( it );
				return ( it != p.second );
                            } );

		if ( is_present )
		{
			std::cout << "There is word \"" << idiot << "\" in the sentence" << std::endl;
		}
		else
		{
			std::cout << "There is no word \"" << idiot << "\" in the sentence" << std::endl;
		}

		std::cout << std::endl;
	}
}
Last edited on
Isn't while( true ) bad practice?
@giblit

Isn't while( true ) bad practice?


I do not see any bad in this statement. It is a general idiom that points out that the exit from the loop will be done inside the loop.

This statement is much better than similar statement

for ( ;; )

I think that you read very bad books on programming if you think that it is a bad practice.:)
Last edited on
@giblit

I think so.... I'm sure I've read that somewhere.
@Code Assassin
I think so.... I'm sure I've read that somewhere.


Do not trust all what is written in books. There are many bad books and there are many examples of how program should not be written. For example books of Stroustrup are full of code that demonstrates how it is should not be written.:)
Last edited on
I didn't read in book I was just curious thx
@giblit

I didn't read in book I was just curious thx


I think that it is because you did not encounter such a construction before.:)
damasta6 wrote:
The reason i'm using the find_first_of function is beacuse the word idiot has to be found in individual characters within an input.

That is still a work for find(), In principle they both do the same thing when the search pattern is just one character, but find is (hopefully) simpler.

http://www.cplusplus.com/reference/string/string/find/
Searches the string for the first occurrence of the sequence specified by its arguments.

Notice that unlike member find_first_of, whenever more than one character is being searched for, it is not enough that just one of these characters match, but the entire sequence must match.


http://www.cplusplus.com/reference/string/string/find_first_of/
Searches the string for the first character that matches any of the characters specified in its arguments.

Notice that it is enough for one single character of the sequence to match (not all of them). See string::find for a function that matches entire sequences.
Thank you all! However, is there a way vlad, that I can make my program without bool functions because that is far beyond what my grade 10 class has taught us. So far, I've taken into account all of your guys' wonderful ideas. I've managed to compile such a program in a very simple manner:
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
36
37
38
39
40
41
#include <iostream>
#include<string>

using namespace std;

int main (int argc, char *argv[])
{
  while(true)
  {
        std::cout<<"Enter a sentence that you would like to check for 'idiot'" <<endl;
        std::string str;
        std::string s1("i");
        std::string s2("d");
        std::string s3("o");
        std::string s4("t");
        std::getline(std::cin,str);
        std::size_t found1=str.find(s1);
        std::size_t found2=str.find(s2);
        std::size_t found3=str.find(s3);
        std::size_t found4=str.find(s4);
        if(found1!=std::string::npos)
        {
            if(found2!=std::string::npos)
            {
                if(found3!=std::string::npos)
                {
                   if(found4!=std::string::npos)
                   {
                        std::cout<<"There is an 'idiot' present in your sentence." <<endl;
                    }
                   
                }
            } 
            
        }
        else
        {
            std::cout<<"There is not an 'idiot' present in your sentence."<<endl;
        }
        
    }


However, this program works if it finds any 'i' 'd' 'o't letters within the input. I need ideas on how to make the program look for them in order such as "i[i] d[d]on't l[i]ke to[o] ea[t]" without using complex functions?
Last edited on
My code contains the idea how to make the program to look the characters in the required order. Investigate it.
Thank you for that Vlad. However, when I try to compile it in Code::Blocks it says that std::string has no member cbegin and cend. It also tells me that all_of is not a member of std. it says it has multiple errors on 'it' and how it "does not mean a type" and how it was not declared in the scopes of lines 27, 28, and 29. Lastly, it tells that 'next' is not a member of std. Is there any way I can fix this?
Did you include his headers?
Pages: 12