#include #include #include #include #define ARR_LEN(X) (sizeof(X) / sizeof(X[0])) typedef enum { START_STATE, DECIMAL_STATE, NUM_STATE, FRACTION_STATE, EXPONENT_STATE, EXP_SIGN_STATE, POWER_STATE, END_STATE, INVALID_STATE, } states; states handle_start(char input); states handle_decimal(char input); states handle_num(char input); states handle_fraction(char input); states handle_exponent(char input); states handle_exp_sign(char input); states handle_power(char input); states state_machine(states current, char input); bool check_number(const char *num); const char *inputs[] = { "0000000", // INVALID "01", // INVALID "f0", // INVALID "1f", // INVALID "1.f", // INVALID "1.0f", // INVALID "8987", // VALID "9.5", // VALID " 7", // VALID " 7.8", // VALID "732.9834e", // INVALID "732.9834e-", // INVALID "732.9834e+", // INVALID "732.9834e-g", // INVALID "732.9834e-8", // VALID "732.9834e+8", // VALID }; int main(int argc, char *argv[]) { for (int i = 0; i < ARR_LEN(inputs); ++i) { printf("%s is %s\n", inputs[i], check_number(inputs[i]) ? "VALID" : "INVALID"); } return EXIT_SUCCESS; } states handle_start(char input) { if (isspace(input)) { return START_STATE; } else if (input == '0') { return DECIMAL_STATE; } else if (isdigit(input)) { return NUM_STATE; } return INVALID_STATE; } states handle_decimal(char input) { if (input == '.') { return FRACTION_STATE; } return INVALID_STATE; } states handle_num(char input) { if (isdigit(input)) { return NUM_STATE; } else if (input == '.') { return FRACTION_STATE; } else if (isspace(input)) { return END_STATE; } return INVALID_STATE; } states handle_fraction(char input) { if (isdigit(input)) { return FRACTION_STATE; } else if (isspace(input)) { return END_STATE; } else if (input == 'e' || input == 'E') { return EXPONENT_STATE; } return INVALID_STATE; } states handle_exponent(char input) { if (isdigit(input)) { return POWER_STATE; } else if (input == '+' || input == '-') { return EXP_SIGN_STATE; } return INVALID_STATE; } states handle_exp_sign(char input) { if (isdigit(input)) { return POWER_STATE; } return INVALID_STATE; } states handle_power(char input) { if (isdigit(input)) { return POWER_STATE; } else if (isspace(input)) { return END_STATE; } return INVALID_STATE; } states state_machine(states current, char input) { switch (current) { case START_STATE: return handle_start(input); case DECIMAL_STATE: return handle_decimal(input); case NUM_STATE: return handle_num(input); case FRACTION_STATE: return handle_fraction(input); case EXPONENT_STATE: return handle_exponent(input); case EXP_SIGN_STATE: return handle_exp_sign(input); case POWER_STATE: return handle_power(input); case END_STATE: case INVALID_STATE: return current; } } bool check_number(const char *num) { states current = START_STATE; for (const char *c = &(num[0]); *c != '\0'; ++c) { current = state_machine(current, *c); if (current == INVALID_STATE) { return false; } } return current == END_STATE || current == NUM_STATE || current == FRACTION_STATE || current == POWER_STATE; }