How to x.find(*any element from array*)

On the sole purpose of learning i've created this simple program that recognizes two possible beginnings of user inputted strings and answer accordingly. On the "bye" section, as you can see, it was a advancement for me to learn the proper use of the || operator in that situation - but of course, there are much more than two ways of saying hi or goodbye. So i made a separated .cpp to host a class that produces the "textsOfHi" array; which appears to be setted up perfectly fine (i shall post it however, may i have forggeted something, i don't know - let me know :3)
Here is the code 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
33
34
35
36
37
38
39
40
#include <iostream>
#include <string>
#include "arrayOfHi.h"
using namespace std;

class Question{
	public:
		int talking = 1;
		std::string userInput;
		std::string userQuestion(){
				
					
    		std::cin >> userInput;
    		if(userInput.find("Hello") == 0){
    			std::cout << "Why, hello there!\n";
			}else{if(userInput.find("bye") || ("Bye") ==0){
				std::cout << "See you next time.\n";
				talking--;
				}
			}
    		return userInput;
	}
		
	
};





int main() {
	
	Question QCall;
	while(QCall.talking == 1){
	
	QCall.userQuestion(); 	
	cout << QCall.talking << endl;} //for monitoring purposes only

	return 0;
}


What i need now is to replace
 
if(userInput.find("Hello") == 0){

With something like:
 
if(userInput.find(arrayOfHi.textsOfHi) == 0){

But has you probably already know, that does not go well.
So... How do i do that?
Also, as a bonus, this is my arrayOfHi.cpp:
1
2
3
4
5
6
7
8
#include "arrayOfHi.h"
#include <iostream>
#include <string>
using namespace std;
arrayOfHi::arrayOfHi(){
	string textsOfHi[] = {"Hi", "hi", "Hello", "hello", "Howdy", "howdy", "Hey", "hey"};
	
}

As you can see, i need to manually discriminate capital letters - is there anyway to tell compiler that it doesn't matter?
Thank you all very much (:

PS: i know i'm using namespace std but still declaring std... idk, it makes me comfortable...
Last edited on
Use the std::find() algorithm.

Correctly comparing two strings with case-insensitivity is actually a fairly complex task, but if you can constrain your inputs to English text, you can get away with a simple toupper() or tolower() transformation.

Here's one way to do it...

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

// Here's our Case Insensitive type...
struct ci
{
  const std::string& s;
  ci( const std::string& s ): s(s) { }
};

// ...and a comparison operator
bool operator == ( const ci& a, const ci& b )
{
  return (a.s.size() == b.s.size()) 
     and std::equal( a.s.begin(), a.s.end(), b.s.begin(), 
           []( char a, char b ) { return std::tolower( a ) == std::tolower( b ); } );
}

int main()
{
  using namespace std;
  
  string greetings[] = 
  {
    "Hello",
    "Greetings",
    "Wazzup",
    "Howdy",
    "Salutations"
  };
  
  string user_greeting;
  cout << "Enter a greeting: ";
  getline( cin, user_greeting );
  
  // Get rid of anything that's not a letter
  user_greeting.erase(
    remove_if( user_greeting.begin(), user_greeting.end(), []( char c ) { return !isalpha( c ); } ),
    user_greeting.end() );

  // Is there any match?
  if (find( begin(greetings), end(greetings), ci(user_greeting) ) != end(greetings))
    cout << "Why hello to you too!\n";
  else 
    cout << "Fine. Be that way!\n";
}

Hope this helps.
Thank you for the answer, it was very insightful and ended up giving me a lot of ideas about my code. However,it didn't solve my problem. As for the capital letter issue, i think i do better hang on that for now, since i was not able to understand most of your code or how to apply it to my own :c
The std::find() suggestion lead me to read this page again, with better attention:
http://www.cplusplus.com/reference/algorithm/find/

But still i couldn't even get to adapt the given example to my code. This is what i wrote (as one of the ideas, i thought it was better to have the find function inside arrayOfHi.cpp instead of main file):

1
2
3
4
5
6
7
8
9
#include <algorithm> 
using namespace std;

arrayOfHi::arrayOfHi(){
	string hi;
	
	string textsOfHi[] = {"Hi", "hi", "Hello", "hello", "Howdy", "howdy", "Hey", "hey"};
	hi = std::find (textsOfHi, textsOfHi+8, "hi");
}

It should be only the first step but won't work already.
This is the line i was trying to adapt:
 
p = std::find (myints, myints+4, 30);

I didn't really understood the meaning of the last parameter, also... Maybe i should just give it a time and keep going with the tutorials for now...
Meanwhile, i would still appreciate any solution very much, of course - if it wouldn't be much of a trouble to address such a clueless aspirant lol
std::find() is the droid you are looking for
I see that you have looked up the documentation for the function (good job!), but you were not careful when you read it. std::find() does not return a string -- it returns an iterator.

For an array, the iterator will be a pointer to the element type. Thus:

string* hi = std::find (textxOfHi, textsOfHi+8, "hi");

I recommend you use the std::begin() and std::end() functions; that allows you to change your table at any time without having to hunt down any magic numbers (like 8):

string* hi = std::find (std::begin(textxOfHi), std::end(textsOfHi), "hi");

You can also use auto to not worry about the actual type of the iterator, for the same reason you should use begin() and end():

auto hi = std::find (std::begin(textxOfHi), std::end(textsOfHi), "hi");

Once you have that iterator, you can check to see whether or not it is valid:

1
2
if (hi != std::end(textsOfHi))
  std::cout << "Yeah! Found it!\n";


Get the last argument in (for good)
Sorry I confused you. I used a lambda -- a function without a name. Many Standard Library functions take as argument a function that compares two elements in a sequence. The following are equivalent:

1
2
3
4
5
6
7
8
9
10
11
// here is a NAMED FUNCTION that compares two characters without case sensitivity
bool compare_ci( char a, char b )
{
  return std::tolower( a ) == std::tolower( b );
}

int main()
{
  std::string one = "Hello";
  std::string two = "hELLO";
  bool ok = std::equal( one.begin(), one.end(), two.begin(), compare_ci );
1
2
3
4
5
6
7
8
9
10
11
int main()
{
  // here is a NAMED LAMBDA that compares two characters without case sensitivity
  auto compare_ci = []( char a, char b ) -> bool
  {
    return std::tolower( a ) == std::tolower( b );
  };

  std::string one = "Hello";
  std::string two = "hELLO";
  bool ok = std::equal( one.begin(), one.end(), two.begin(), compare_ci );
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
  std::string one = "Hello";
  std::string two = "hELLO";
  bool ok = std::equal( one.begin(), one.end(), two.begin(), 
    // Here is an UNNAMED LAMBDA that compares two characters without case sensitivity
    []( char a, char b ) -> bool
    {
      return std::tolower( a ) == std::tolower( b );
    }
  );
}

You can recognize the lambda by it's syntax:

    [ stuff ] ( arguments ) -> result_type { body }

For comparison, here's a named function:

    result_type name( arguments ) { body }

If you do not specify the result_type for a lambda, the compiler will endeavor to guess. (It's pretty good at that.)

Hope this helps.
Topic archived. No new replies allowed.