1

I'm trying to program a simple state machine for an assignment. The assignment is to build a code that, given a string for input, can start at the β€œCat” state, and perform actions until I run out of information.

Here's a chart which portrays what I'm trying to do:

chart


Now, I've almost finished the code but there's a problem within a function. I am getting the error "invalid operands to binary expression ('State' and 'State')" Can someone give me a hint on how to correct this problem and a brief explanation on what's wrong? The problem is with using struct types in an if..else statement.

I have this portion of the code before int main():

struct State{
  string A, B;
};

State Cat = {"Meow", "Ignore"};
State Noise = {"Boing", "Thud"};
State Food = {"Lemons", "Cinnamon"};

State mystate = Cat;

 //my_state.A -> string 

And here is the function where the error is:

void change_state(char c) {
  // on taking character c, it changes current state
  // If state is Cat and I get 1 , change to Food
  // If state is Cat and I get 2 , change to Noise
  // If state is Food and I get 1 , change to Noise
  // If state is Food and I get 2 , change to Cat
  // If state is Noise and I get 1 , change to Cat
  // If state is Noise and I get 2 , change to Food

  if (mystate == Cat){  //error 
    if (c == '1') {
      mystate = Food;
    }
    else {
      mystate = Noise;
    }
  }
  else if (mystate == Food) {
    if (c == '1') {
      mystate = Noise;
    }
    else {
      mystate = Cat;
    }
  }
  else  {
    if (c == '1') {
      mystate = Cat;
    }
    else {
      mystate = Food;
    }
  }
}

Any help will be appreciated!

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

3 Answers3

2

To compare custom types with ==, you need to overload operator== for the type, to specify when two objects of that type are considered equal.

For example:

bool operator==(State const& left, State const& right) {
  return left.A == right.A && left.B == right.B;
}

Now when you use == on two States, this function gets called.

More info: Operator overloading

Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
2

As @zenith pointed out, what you are asking for can be done, using operator overloading. However, using a struct as a state value doesn't really make sense. You can use an enum instead, which is more inline with your flow chart anyway:

enum State {Cat, Noise, Food};
string StateStrings[3][2];

...

StateStrings[Cat][0] = "Meow";
StateStrings[Cat][1] = "Ignore";

StateStrings[Noise][0] = "Boing";
StateStrings[Noise][1] = "Thud";

StateStrings[Food][0] = "Lemons";
StateStrings[Food][1] = "Cinnamon";

State mystate = Cat;

...

void change_state(char c)
{
  // on taking character c, it changes current state
  // If state is Cat and I get 1 , change to Food
  // If state is Cat and I get 2 , change to Noise
  // If state is Food and I get 1 , change to Noise
  // If state is Food and I get 2 , change to Cat
  // If state is Noise and I get 1 , change to Cat
  // If state is Noise and I get 2 , change to Food

  switch (mystate)
  {
    case Cat: {
      switch (c) {
        case '1': mystate = Food; break;
        case '2': mystate = Noise; break;
      }
      break;
    }
    case Noise: {
      switch (c) {
        case '1': mystate = Cat; break;
        case '2': mystate = Food; break;
      }
      break;
    }
    case Food: {
      switch (c) {
        case '1': mystate = Noise; break;
        case '2': mystate = Cat; break;
      }
      break;
    }
  }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

First, I think you can define a constructor for the struct

State(cosnt string& a, const string &b):A(a), B(b){}  

Second, besides the solution provided by zenith,you can define a member function operator== instead:
bool State::operator==(State const& right) { return this->A == right.A && this->B == right.B; }

Yuan Wen
  • 1,583
  • 3
  • 20
  • 38