0

So I recently finished a beginner'c course on C++, and wanted to make my own "chat bot" since apparently it's easy and been done a million times. The problem I'm having, is that when the user input matches more than one possibility in my 'if' statement, it issues the command more than once.

class response{
public:
    void answer() {
    string x;
    cin >> x;

    if (x=="Hello"||x=="hello"||x=="Hi"||x=="hi"||x=="hey"||x=="Hey") {
        cout << endl << "Hello!" << endl << endl;
    }
    else {
        cout << endl << "I didn't understand that." << endl << endl;
    }
    } };

For example, if you input: "hey hi", you get: "Hello! Hello!"

Or if you input "hey squid" you get "Hello! I didn't quite understand that."

And so on and so on. I'm wondering if there is any way to make it so that, unless your entire string matches the exact x== values, it will execute the else statement, and only execute it once.

Edit: The solution worked. Thanks for all the help! Some of you were asking about how I was using the class statement in main. I hope this helps clarify how I used it:

int main()
{
    cout << "Hello! I am Drew Bot 1.0." << endl << endl;
    for(;;){
    response test;
    test.answer();
    }

}
Drew Pesall
  • 179
  • 3
  • 12
  • 1
    Can you show how you're using `response::answer()`? – Alex Meuer Jan 09 '17 at 08:22
  • What have you actually tried that would check if `x` contains one of more of the strings being tested? Do you expect your code to deal with multiple matching strings on one line, or do you expect it to deal with multiple matches that may be on different lines? – Peter Jan 09 '17 at 08:23
  • 1
    `std::string` is delimited with space when taking input with `std::cin`. So here you are taking more than one input(if calling `answer` within a loop). Try it with `std::getline` – Zeeshan Akhter Jan 09 '17 at 08:25
  • @ZeeshanAkhter is right. Typing multiple words into `cin` and streaming it to a string will only take the first token. The remaining tokens will remain in `cin` until you `>>` them into a variable. – Alex Meuer Jan 09 '17 at 08:32
  • I'd probably put all of those valid strings into an std::unordered_set, and call std::unordered_set::count(x) to see if it's valid. – Vada Poché Jan 09 '17 at 08:47
  • 1
    Unrelated: I can't help but notice your overzealous use of `std::endl`. Consider replacing some with the newline character `\n`. More info here: http://stackoverflow.com/a/214076/4571656 – Alex Meuer Jan 09 '17 at 08:50

1 Answers1

2

For what you describe to occur (and it would make sense because you're writing a chat bot), response::answer() would have to be called in a loop.

The tokens of std:cin are delimited by the space character, so when you stream it into a variable you are only getting the first word and the rest of the words remain in the std::cin stream. The part that is catching you is that is if std::cin already has a token, it does not wait for user input.

So, if you type "hey hi hello squid" in the first call to response::answer, it will only check the first word. Subsequent calls will check the rest of the words without prompting the user until nothing remains in the input stream.

A solution would be to use getline (std::cin, x); in place of std::cin >> x.
getline will read to the next newline or EOF, but you can also specify your own delimiter: getline(std::cin, x, ' ');

Alex Meuer
  • 1,621
  • 3
  • 26
  • 37
  • This worked! Thank you! And sorry I did not include how I used class response, but yes I did use it in a loop using: for(;;){ response test; test.answer(); } – Drew Pesall Jan 09 '17 at 19:40