Finding letters in a string

Pages: 12
May 20, 2013 at 2:47am
#include <iostream>
#include<string>
#include<sstream>
using namespace std;

string idiot="idiot";
string capidiot="Idiot";
string userinput;

cout<<"Gimme a sentence to check for "idiot":";
getline(cin, userinput);

void findidiot(userinput)
{
int numofletters=5;
for (n=0;userinput[n]!='N';n++)
if (userinput[n]==idiot[n]||userinput[n]==capidiot[n]) numofletters++;
else numofletters=0;
if (numofletters==5) {cout<<"The sentence contains "idiot"; break;}
else cout<<"The sentence does not contain "idiot"; break;
}

Wrote it in the reply box and didn't try to compile it, but barring a few bugs/typos it should work.
Last edited on May 20, 2013 at 2:48am
May 20, 2013 at 2:50am
Or in other words, what I said yesterday.
May 20, 2013 at 8:40am
@damasta6

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.


I think you made a typo. Simply copy and paste the code. You can try it on-line at www.ideone.com. cbegin and cend are standard member functions of class std::string.
May 20, 2013 at 12:19pm
I bet it is C++11 code and noncompliant compiler. Does that C:B call compiler that supports C++11?
May 20, 2013 at 5:30pm
I see what the problem is. The code is (like keskiverto said) in c++. Unfortunately the computers i'm working on use c++ 4.7.2 and my code needs to be compatible with that compiler. However, I thank you all and really appreciate your help!
May 20, 2013 at 6:04pm
What is "c++ 4.7.2"? If it is gcc, then add the -std=c++11 option.
May 21, 2013 at 9:14pm
Thanks but it is impossible for me to add any options to a program in my school's computer. I have to make this program without using c.begin and c.end, because they are member of the c++11 option which I do not have access to.

Is there a way in which I can make the program verify whether the position of the character 'i' is before 'd' which is before 'o' etc in standard gcc (not c++11) in my code?:

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
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;
	        }

	    }
May 21, 2013 at 9:17pm
Use begin and end then? The c is for constant iterator instead of normal iterator
May 21, 2013 at 9:33pm
Impossible? http://lesswrong.com/lw/ui/use_the_try_harder_luke/
You call the compiler. You set the options for the compiler. (And you did not answer which exact compiler do you have.)


Originally you did have an almost-there approach. At first you find the first "i". You either find one, or fail. Then (if you have not failed yet) you should look for the "d" from the rest of the sentence. Again, you either find it or fail. Repeat until you either have failed or have found all the letters.

Alternatively, replace each C++11 specific bit. Before lambdas, there were function objects. Before auto, one wrote explicit types. Before iterators, there were pointers.
May 21, 2013 at 11:23pm
I decided to make a program from scratch and it works. It won't allow you to check multiple sentences, but it works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
printf("Type in what you want to check for the word 'idiot'.");
    fflush(stdout);
    fgets(input, 100, stdin);
    for (int i = 0; input[i]!=0; i++) {
        if (input[i]=='i'||input[i]=='I') {
            if (input[i+1]=='d'||input[i+1]=='D') {
                if (input[i+2]=='i'||input[i+2]=='I') {
                    if (input[i+3]=='o'||input[i+3]=='O') {
                        if (input[i+4]=='t'||input[i+4]=='T') {
                            if (a==true){} else {
                            printf("The word idiot is in that sentence.\n");
                            a = true;
                            }
                        }
                    }
                }
            }
        }
    }
    if (a!=true) {
        printf("The word idiot is not in that sentence.");
    }

May 22, 2013 at 3:25am
@dunnmiffisys: No, that does not "work". First, it does not do what OP's program should. Second, it references uninitialized memory.

Its only merit is case insensitivity.
May 22, 2013 at 5:24am
@keskiverto Yes it does. That's exactly what he's trying to do. And I didn't include main or bool a, but that takes a whopping two seconds.
May 22, 2013 at 5:46am
damasta6 wrote:
... 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)".
May 22, 2013 at 8:54pm
So in my case, keskiverto, would it still be more beneficial to use the find() function or the find_first_of function?
May 22, 2013 at 9:49pm
'find'. I think I already did explain why.

The std::all_of is a loop. Look at its documentation in the reference section.

The lambda expression is a function, and vlad's version keeps state. During one call of that function:
1
2
3
4
5
6
7
8
9
10
11
12
13
bool test( char c, std::size_t & pos, const std::string & text ) {
  // pos is assumed to point just after previous found character
  // pos was 0 before first call, and 0 is the "just after" beginning of text
  // if last call did fail, this call should never occur
  pos = text.find( c, pos );
  if ( std::string::npos == pos ) {
    return false;
  } else {
    ++pos;
    // now pos is again pointing to just after what we have found so far
    return true;
  }
}
May 22, 2013 at 9:54pm
I think I managed to complete my program successfully. This is what I have done.
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
44
45
46
47
48
49
50
51
52
53
54
55
std::string str;
		std::cout<<"Give me a sentence to check for 'idiot'."<<endl;
		std::getline(std::cin,str);
		  unsigned found = str.find_first_of("i");
		  unsigned found1 = str.find_last_of("d");
		  unsigned found2 = str.find_last_of("o");
		  unsigned found3 = str.find_last_of("t");
		  if (found!=std::string::npos)
		  {

		    found=str.find_first_of("i");
		    if(found1>found)
		    {
		    	if(found1!=std::string::npos)
		    	{
		    		
		    		found1=str.find_last_of("d");
		    		if((found1>found)&&(found2>found1))
		    		{
		    			if(found2!=std::string::npos)
		    			 {
		    			    
		    			    found2=str.find_last_of("o");
		    			    if((found3>found2)&&(found2>found)&&(found1>found))
		    			    {
		    			    	if(found3!=std::string::npos)
		    			    	{
		    			    		found3=str.find_last_of("t");
		    			    		cout<<"There is an 'idiot' and the letters are in the exact order." <<endl;
		    			    	}
		    			    }
		    			    else
		    			    {
		    			    	std::cout<<"No idiots here. "<<endl;
		    			    }

		    			 }

		    		}
		    		else
		    		{
		    			std::cout<<"No idiots here." <<endl;
		    		}

		    	}
		    }
		    else
		    {
		    	cout<<"No idiots here. "<<endl;
		    }
		  }
		  else
		  {
			  std::cout<<"No idiots here " <<endl;
		  }
Last edited on May 22, 2013 at 9:58pm
May 23, 2013 at 1:31am
I think I managed to complete my program successfully. This is what I have done.


That looks like it'll (almost) get the job done. You don't check to see if there is a second 'i' in your input. Have you tried "idot" as your input?

You should consider:

http://www.cplusplus.com/reference/string/string/find/

You should note that all of the string::find functions take a parameter which indicates where to start the search from. This means, that if you find the first 'i' in your input string, you can start your search for the 'd' from directly after where you found the first 'i', and so on for each consecutive letter you're looking for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    std::string str;
    std::cout<<"Give me a sentence to check for 'idiot'."<<endl;
    std::getline(std::cin,str);

    const std::size_t not_found = std::string::npos ;

    bool found = false ;
    std::size_t idx ;
    if ( (idx = str.find('i')) != not_found )
        if ( (idx = str.find('d', idx)) != not_found ) 
            if ( (idx = str.find('i', idx)) != not_found )
                if ( (idx = str.find('o', idx)) != not_found )
                    if ( (idx = str.find('t', idx)) != not_found )
                        found = true ;

    if ( found )
        std::cout << "There is..." ;
    else
        std::cout << "There is not..." ;
Last edited on May 23, 2013 at 1:32am
May 23, 2013 at 2:03am
I dunno if your still working on it but I found this solution to check thru sentence for a character, you can adjust it to your needs.

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
#include <iostream>
#include <string>

using namespace std;


int main()
{
 string in;
 cout << "enter a sentence" << endl;
 getline(cin, in);
 int pos = 1;
 for(auto i = in.begin(); i != in.end();++i,++pos){
    switch(*i){
    case 'i':
        cout << "Character i was found it position " << pos << endl;
        break;
    case 'd':
        cout << "Character d was found it position " << pos << endl;
        break;
    case 'o':
        cout << "Character o was found it position " << pos << endl;
        break;
    case 't':
        cout << "Character t was found it position " << pos << endl;
        break;
                }
        }
    }
Last edited on May 23, 2013 at 2:17am
Topic archived. No new replies allowed.
Pages: 12