Anonymous user
Finite state machine: Difference between revisions
→{{header|C}}
Line 72:
=={{header|C}}==
Here is a manually-constructed table-driven finite state machine that implements the same algorithm as the previous spaghetti code version.
<lang C>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char **argv)
{
typedef enum State { READY, WAITING, REFUND, DISPENSE, COLLECT, QUIT, EXIT } State;
typedef struct statechange {
const int in;
const State out;
} statechange;
typedef struct FSM {
const State state;
const char *prompt;
const int inputs;
const statechange table[3]; // hacky. would be dynamic in a real program.
} FSM;
const FSM fsm[6] = {
{ READY, "\nMachine is READY. (D)eposit or (Q)uit :", 3, {{'D', WAITING}, {'Q', QUIT }, {-1, READY}} },
{ WAITING, "(S)elect product or choose to (R)efund :", 3, {{'S', DISPENSE}, {'R', REFUND}, {-1, WAITING}} },
{ REFUND, "Please collect refund.\nMachine is READY. (D)eposit or (Q)uit :", 3, {{'D', WAITING}, {'Q', QUIT }, {-1, REFUND}} },
{ DISPENSE, "Dispensing product...\nPlease (C)ollect product. :", 3, {{'C', READY}, { -1, COLLECT }, {-1, DISPENSE}} },
{ COLLECT, "Please (C)ollect product. :", 2, {{'C', READY}, { -1, COLLECT }, {-1, COLLECT}} },
{ QUIT, "Thank you, shutting down now.\n", 1, {{ -1, EXIT}, { -1, EXIT }, {-1, EXIT}} },
};
char str[10]; // hacky. from prev Rosetta Code example before rewriting.
int each;
State state = READY;
do {
fprintf(stderr, "%s", fsm[state].prompt); fflush(stderr);
if (fsm[state].table[0].in < 0 && fsm[state].table[0].out == EXIT) break; else scanf("%s", str);
for (each = 0; each < fsm[state].inputs; each++) {
if (fsm[state].table[each].in < 0) { state = fsm[state].table[each].out; break; }
else if (isalpha(str[0]) && toupper(str[0]) == fsm[state].table[each].in) { state = fsm[state].table[each].out; break; }
}
} while (state != EXIT);
}
</lang>
|