Finding a string within an array

Hey guys i just want to check to see if one word (string) or one sentance is equal to any others within an array. My code

so basically i want to check if a is equal to either "sleep", "in", or "bed". Or even if the string within a is equal to "sleep in bed" as one string.

I have used the following but even if i get it correct and it says correct it says incorrect another 2 times because it is saying yeah you have gotten one right out of the possible 3. Even if I type "sleep in bed" it still does it (prints out incorrect another 2 times. Also are there any good books to start off with c++?


1
2
3
4
5
6
7
8
9
10
11
12
13
string a;
string aa[3] = {"sleep", "in", "bed"};
        for(int i = 0; i < 3; i++)
        {
        if(a == aa[i])
        {
            cout << "CORRECT!" << endl;
        }
        else
        {
            cout << "INCORRECT!" << endl;
        }
        }


Thank you in advance
You haven't initialized a so it is unlikely to equal any of the elements in array string aa[3]. E.g. change L1 to string a = {"in"}; Then when i==1 the snippet should return "correct
Last edited on
oh lol, soz it's meant to be like this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string a;
string aa[3] = {"sleep", "in", "bed"};

cin >> a;

        for(int i = 0; i < 3; i++)
        {
        if(a == aa[i])
        {
            cout << "CORRECT!" << endl;
        }
        else
        {
            cout << "INCORRECT!" << endl;
        }
        }


so a = user input
Your for-loop is going to compare the value entered by the user to all the values in the array and since you are checking the single word entered by user against all the words, even if you did type in one word that works, you will still get INCORRECT for the other words that are not matching what you entered.

So what you want to do is to have a boolean that is set to false before your for-loop. The for loop should only have the if-statement in it not the else. When you find a match, set the boolean to true and break out of the for-loop. Now you just have to check the boolean, if it is still false after the for-loop has run then print the "INCORRECT" statement.
ok, now my code is...

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
string a;
string aa[3] = {"sleep", "in", "bed"};
bool aaa = false;
int number = 1;
string b;
string bb[2] = {"hello","world"};
bool bbb = false;

while(number == 1)
{
cout << "Enter: sleep in bed" << endl;
cin >> a;

        for(int i = 0; i < 3; i++)
        {
            if(a == aa[i])
            {
                cout << "CORRECT!" << endl;
                aaa = true;
                number = 2;
                break;
            }

        }
        if(aaa == false)
        {
            cout << "Incorrect"<< endl;
        }
}

while(number == 2)
{
cout << "HELLO WORLD!" << endl;
cin >> b;

        for(int i = 0; i < 2; i++)
        {
            if(b == bb[i])
            {
                cout << "CORRECT!" << endl;
                aaa = true;
                number = 2;
                break;
            }

        }
        if(bbb == false)
        {
            cout << "Incorrect"<< endl;
        }
}


so now if i type, "sleep in bed" for the value of string a, it takes me to the next bit where i should enter Hello World, but, beacuse "sleep" is correct it takes me straight to the Hello World part and also beacuse "in" and "bed" are incorrect for the Hello World Part. This make the out put be "Incorrect" twice.
Last edited on
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
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
  char aa[] = {"sleep in bed"};
  char* a = new char[sizeof aa / sizeof aa[0]];
  int number = 1;
  char bb[] = {"hello world"};
  char* b = new char[sizeof bb / sizeof bb[0]];
  
  while(number == 1)
  {
    cout << "Enter: sleep in bed: ";
    cin.getline(a, sizeof aa / sizeof aa[0]);
    
    if(strcmp(a, aa) != 0)
      cout << "INCORRECT!\n" <<endl;
    
    else 
    {
      ++number;
      cout << "CORRECT!\n"<<endl;
    }
  }
  
  cout <<"Good job!\n";
  while(number == 2)
  {
    cout << "Enter: hello world: ";
    cin.getline(b, sizeof bb / sizeof bb[0]);
    
    if(strcmp(b, bb) != 0)
      cout << "INCORRECT!\n";
    
    else
    {
      ++number;
      cout << "CORRECT!\n";
    }
  }
  return 0;
}


$ ./File
Enter: sleep in bed: sleep in bed
CORRECT!

Good job!
Enter: hello world: hello world
CORRECT!


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
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;

int main()
{
  string aa = "sleep in bed";
  char a[15];
  int number = 1;
  string bb = "hello world";
  char b[15];
  size_t posA;
  size_t posB;
  
  while(number == 1)
  {
    cout << "Enter: sleep,  in,  bed: ";
    cin.getline(a, (int)aa.size(), '\n');
    
    posA = aa.find(a);
    if (posA == string::npos)
      cout << "INCORRECT!\n" <<endl;
    
    else 
    {
      ++number;
      cout << "CORRECT!\n"<<endl;
    }
  }
  
  cout <<"Good job!\n";
  while(number == 2)
  {
    cout << "Enter: hello, world: ";
    cin.getline(b, (int)bb.length(), '\n');
    
     posB = bb.find(b);
     if (posB == string::npos)
      cout << "INCORRECT!\n";
    
    else
    {
      ++number;
      cout << "CORRECT!\n";
    }
  }
  return 0;
}



$ ./File
Enter: sleep,  in,  bed: bes
INCORRECT!

Enter: sleep,  in,  bed: sleeep
INCORRECT!

Enter: sleep,  in,  bed: sleep
CORRECT!

Good job!
Enter: hello, world: helo
INCORRECT!
Enter: hello, world: hello
CORRECT!
Last edited on
@Texedova
so basically i want to check if a is equal to either "sleep", "in", or "bed". Or even if the string within a is equal to "sleep in bed" as one string.


In fact you need to check that at least one word of the string array is contained in string a. It can be done the following way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

int main() 

{
	std::string a[3] = { "sleep", "in", "bed" };

	std::string s( "Power in the truth" );

	if ( std::any_of( std::begin( a ), std::end( a ), 
		[&s]( std::string x ) { return ( s.find( x ) != std::string::npos ); } ) )
	{
		std::cout << "Correct!\n";
	}
	else
	{
		std::cout << "Incorrecr!\n";
	}
}
Last edited on
Oh, it seems that I was wrong. If I have correctly understood your task then you should check whether the input string consists exactly from three words in the specified order in the array do not taking into account blanks or it equal to one of the words.

For example, this input string

"_____sleep____in____bed___"

satisfies the condition (here undescores denote spaces)

and this input string also satisfies ths condition


"__________in___"

because it will be equal to one of the words in the array if to remove spaces.

If I am right then you need to write two functions. The first one (let name it as trim) will renove leading and trailling spaces. The second one will compare the result string with the words in the array.
Last edited on
closed account (3TXyhbRD)
Smac89 wrote:
So what you want to do is to have a boolean that is set to false before your for-loop. The for loop should only have the if-statement in it not the else. When you find a match, set the boolean to true and break out of the for-loop. Now you just have to check the boolean, if it is still false after the for-loop has run then print the "INCORRECT" statement.

-1 for suggesting the use of break.

If you need to iterate, at most, through all entries then use while/do.. while and not a for. The least is meant for loops where you know how many times you have to cycle (hence the name for).

vlad from moscow wrote:
If I am right then you need to write two functions. The first one (let name it as trim) will renove leading and trailling spaces. The second one will compare the result string with the words in the array.

I'd rather call the first slipt() and not trim since blanks between words matter not.

The way I would go at it:
Split the phrase to get an array of words.
Split the "looking for" phrase to get an array of lookingForWords.
Check if words contain lookingForWords.

E.g.:
phrase:        "     sleep             in          bed       "
lookForPhrase: "        in             bed           "

words:           split(phrase) => {"sleep", "in", "bed"}
lookingForWords: split(lookingForPhrase) => {"in", "bed"}

words[0] != lookingForWords[0]
words[1] == lookingForWords[0] && words[2] == lookingForWords[1] => CORRECT!


phrase: "     sleep             in          bed       "
lookForPhrase: "       apple "

words:           split(phrase) => {"sleep", "in", "bed"}
lookingForWords: split(lookingForPhrase) => {"apple"}

words[0] != lookingForWords[0]
words[1] != lookingForWords[0]
words[2] != lookingForWords[0]
=> INCORRECT!
@Andrei15193
I'd rather call the first slipt() and not trim since blanks between words matter not.


To compare one word it is enough to use trim. To compare a sentence there is no need trimming or splitting because there is std::istringstream that allows to compare its separate words.

In fact the realization is simple

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::vector<std::string> v;
v.reserve( std::distance( std::begin( aa ), std::end( aa ) ) );

std::copy( std::istream_iterator<std:;string>( std::istringstream( a ) ),
                std::istream_iterator<std::string>(),
                std::back_inserter( v ) );

if ( v.size() == sizeof( aa ) / sizeof( *aa ) && std::equal( v.begin(), v.end(), aa )  ||
     v.size() == 1 && std::find( std::begin( aa ), std::end( aa ), v.front() ) != std::end( a ) )
{
   std:;cout << "Correct\n";
}
else
{
   sttd::cout << "Incorrect\n";
}



If I have not made a typo then this code will give what is required.:)

EDIT:
Last edited on
closed account (3TXyhbRD)
Functional-ish solution. NICE! I didn't have istringstream in mind when I wrote my solution, was think more general.
Here is a tested 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
std::string a[3] = { "sleep", "in", "bed" };
std::string s( " sleep  in    bed   " );

auto equal_to_one_of = [] ( const std::vector<std::string> &v, const std::string ( &a )[3] )
{
	return
	( ( v.size() == 3 && 
	    std::equal( v.begin(), v.end(), a ) 
	  ) 
	  ||
	  ( v.size() == 1 && 
	    std::find( std::begin( a ), std::end( a ), v.front() ) != std::end( a ) 
	  )
	);
};

std::vector<std::string> v;
v.reserve( std::distance( std::begin( a ), std::end( a ) ) );

std::copy( std::istream_iterator<std::string>( std::istringstream( s ) ),
       std::istream_iterator<std::string>(),
   std::back_inserter( v ) );

if ( equal_to_one_of( v, a ) )
{
	std::cout << "Corrrect\n";
}
else
{
	std::cout << "Incorrect\n";
}

s = ( "   in       " );

v.clear();
std::copy( std::istream_iterator<std::string>( std::istringstream( s ) ),
       std::istream_iterator<std::string>(),
   std::back_inserter( v ) );


if ( equal_to_one_of( v, a ) )
{
	std::cout << "Corrrect\n";
}
else
{
	std::cout << "Incorrect\n";
}


I did not use declarations

const size_t N = 3;
std::string a[N] = { "sleep", "in", "bed" };

becuase MS VC++ 2010 has a bug then a constant ( I mean N in this case) is used in a lambda expression. It requires to capture it though according to the C++ Standard it is not needed.
If do not take into account this bug of MS VC++ 2010 I would write the lambda the following way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const size_t N = 3;
std::string a[N] = { "sleep", "in", "bed" };
std::string s( " sleep  in    bed   " );

auto equal_to_one_of = [] ( const std::vector<std::string> &v, const std::string *a )
{
	return
	( ( v.size() == N && 
	    std::equal( v.begin(), v.end(), a ) 
	  ) 
	  ||
	  ( v.size() == 1 && 
	    std::find( a, a + N, v.front() ) != a + N 
	  )
	);
};
Last edited on
Thank you everyone but, are there any tutorials on this stuff so i can understand your codes a bit more? I mean i understand basic stuff such as you know, functions, while loops, a bit of arrays, int, float, double, long, string, for loops etc. I am still a beginner in c++ and have moved over to it from java, so yeah some basic stuff from java is almost the same as c++.
Last edited on
lIn my opinion a good book is "Thinking in C++" by Bruce Eckel and Chuck Allison ( in two volumes).
Though it is based on the previous C++ Standard it is actual till now.
Last edited on
Are there any tutorials in on the internet such as video tutorials? I am planning on buying a book soon but i still want to understand this code i have been given as soon as possible. If it is any help for others to help me (that sounds so sad, makes me sound selfish :( anyway ), I am actually trying to create a small text adventure game, just as i go in learning c++.
closed account (9y8C5Di1)
//This will check if your input is equal to any of the words in the array that are seperated with a "space"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
string input;
getline(cin, input);

string elements[] ={"person","is","fragments person"},temp,matches="";

for(unsigned int x = 2;x>0;--x){temp="";
  for(unsigned int y = 0;elements[x][y]!='\0';++y){
   //assuming for each space, comes a new word
   if(!elements[x][y]==' ')
    temp+=elements[x][y];
     else
    temp = "";
   if(temp == input)
    matches+=temp;
 }
} 



input: person
matches = personperson


If the current string of the array is "personperson", only the first person will be applied. because after the first person a space is still not encountered, and therefore it will proceed and add an 'p' to temp which will then equal "personp", and therefore not catch the second identical word. You could solve this by reassigning temp whenever temp = input. Like: if temp==input assign temp ""
Last edited on
This 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
#include <iostream>

using namespace std;

int main()
{

    string input;
    getline(cin, input);

    string elements[] ={"person","is","fragments person"},temp,matches="";

    for(unsigned int x = 2;x>0;--x){temp="";
      for(unsigned int y = 0;elements[x][y]!='\0';++y){
       //assuming for each space, comes a new word
       if(!elements[x][y]==' ')
        temp+=elements[x][y];
         else
         temp = "";
         if(temp == input)
         matches+=temp;
      }
    }
          cout << matches << endl;
          cout << temp << endl;
    return 0;
}


Doesn't print any matches, i even added 2 cout lines to print matches and temp and nothing gets printed. Am i missing something or doing something wrong or...
line 13: You are not going to the end of your strings in elements i.e. element[0] is ignored

line 16: I think you were concentrating far too much on not including space that you basically just eliminate any real matches when space is found

line 17: You are just adding characters to your temp and not putting any checks to see if they are what you are looking for

line 14: Instead of using elements[x][y]!='\0';, use y < elements[x].length();. It's not really a big deal, but if you happen to have a zero in your string, then the code will fail worse than it had

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
56
57
58
59
60
61
#include <iostream>
using namespace std;

int main()
{
  
  string input;
  cout << "Enter word to search for: ";
  getline(cin, input);
  
  bool gotM = false;
  string elements[] ={"person","is","fragments person"};
  string temp;
  string matches="";
  
  for(int x = 0; x < 3; ++x)//go through all the words in the elements array
  {
    temp="";//Set temp to empty
    gotM = false;
    for(int y = 0; y < (int)elements[x].length(); ++y)//go through the characters in the current word
    {
      if(elements[x][y] == input[0])//First we look for our first character in the current word
      {
	int f = y;//f will act as a dummy varaible so we don't change value of y
	for (int t = 0; t < (int)(input.length()) && (t+y) < (int)(elements[x].length()); ++t, ++f)
	  //basically, go through the length of our word and search for matches
	  //while not going over the length of the string we are searching in
	{
	  if (input[t] == elements[x][f])
	    temp += elements[x][f];//add any matching characters to temp
	  else
	  {
	    temp = "";
	    break;
	  }
	  //if it the string we are searching in just contains part of
	  //the search string, we set temp back to empty  
	    
	}
	if (!temp.empty() && temp.length() == input.length())
	//Make sure we got a true match by comparing length of temp 
	//to that of our search string
	{
	   matches+=temp + " from string " + elements[x] + " \n";
	   //Add the match and the string it came from
	   gotM = true;
	}
      }
      else if (gotM)
	break;
    }
  }
  if (!matches.empty())
  {
    cout <<"\nFound the following matches for " << input <<":" <<endl;
    cout << matches << endl;
  }
  else
    cout <<"\nFound no matches for " << input <<endl;
  return 0;
}



$ ./String\ Search
person
person from person 
person from fragments person

$ ./String\ Search
Enter word to search for: son

Found the following matches for son:
son from string person 
son from string fragments person

$ ./String\ Search
Enter word to search for: fragr

Found no matches for fragr

$ ./String\ Search
Enter word to search for: frag

Found the following matches for frag:
frag from string fragments person
Last edited on
closed account (9y8C5Di1)
Ok, i wrote that one in hurry. This one is even tested, and works.

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
#include <iostream>
using namespace std;

unsigned short reMatch(string array[],short lenght,string input = "per is nothing"){

unsigned short count = 0;

 for(string current_word="",temp="";lenght>=0;--lenght){
	for(unsigned short x = 0,word_lenght=0;input[x]!='\0';++x,word_lenght=0,current_word=""){
	  	
	  	//obtain the next word, and its lenght
	  	for(;input[x]!=' ';++x,++word_lenght){
			if(input[x]=='\0')
			 break;
			current_word+=input[x];
		}
		//compare the current word with the words in the current string of the array, and use the current_word's lenght as condition
		//if temp's lenght is higher than current_word's lenght, and they are not equal, then we can reset temp, and begin to scan
		//from the previous start point + 1
		
		for(unsigned int y=0,temp_lenght=0;array[lenght][y]!='\0';++y){
			
			temp+=array[lenght][y];++temp_lenght;
			
			if((temp==current_word&&temp_lenght==word_lenght)){
				++count;temp="";
				y-=(temp_lenght-1);temp_lenght=0;
				cout<<current_word<<endl;
			}
			if(temp_lenght>word_lenght){
				temp = "";
				y-=(temp_lenght-1);temp_lenght=0;
			}
				
		}
	}
 }
	
	return count;
}



int main(){

     string a[]={"periamnotper","whoareyou iam you no one","okcoolyeah"};

    //type in third param what you want to find
     cout<<reMatch(a,2,"who you i am cool");

    	
	return 0;
}


output:

who
you
you
i
i
am
am
cool
8


It got problems, with the first letter of the array, but you can fix that; it does not actually find "who"
Last edited on
Topic archived. No new replies allowed.