views:

134

answers:

1

I'm writing a program to basically check if a number is a type float, double, or long double for an assignment using switch statements and a state machine. I am stepping through my program, and it gets all the way to the end except doesn't seem to recognize the string terminator '\0'. So I was wondering if that portion of my code is correct. I included the whole code, but with an input like 0.0F, it gets all the way to the F_END state, and then does not return TYPE_FLOAT, but instead returns NOTFLOATING and I don't see why it doesn't enter the case '\0': statement.

StatusCode DetectFloats(const char *cp) 
{
    enum States {
        START,
        NO_WHOLE,
        WHOLE,
        FRACT,
        EXPONENT,
        PLUS_MINUS,
        DIGIT,
        F_END,
        L_END
    } state = START;

    while (*cp != '\0') {
        switch (state) {

        case START:
            switch (*cp) {
                case '.':
                    state = NO_WHOLE;
                    break;
                default:
                    if (isdigit(*cp)) {
                        state = WHOLE;
                    }
                    else {
                        return NOTFLOATING;
                    }
                    break;
            }
            break;

        case WHOLE:
            switch (*cp) {
                case '.':
                    state = FRACT;
                    break;
                case 'e':
                case 'E':
                    state = EXPONENT;
                    break;
                default:
                    if (isdigit(*cp)) {
                        state = WHOLE;
                    }
                    else {
                        return NOTFLOATING;
                    }
                    break;
            }
            break;
        case FRACT:
            switch (*cp) {
                case 'f':
                case 'F':
                    state = F_END;
                    break;
                case 'l':
                case 'L':
                    state = L_END;
                    break;
                case 'e':
                case 'E':
                    state = EXPONENT;
                    break;
                case '\0':
                    return TYPE_DOUBLE;
                default:
                    if (isdigit(*cp)) {
                        state = FRACT;
                    }
                    else {
                        return NOTFLOATING;
                    }
                    break;
            }
            break;
        case EXPONENT:
            switch (*cp) {
                case '+':
                case '-':
                    state = PLUS_MINUS;
                    break;
                default:
                    if (isdigit(*cp)) {
                        state = DIGIT;
                    }
                    else {
                        return NOTFLOATING;
                    }
                    break;
            }
            break;
        case PLUS_MINUS:
            switch (*cp) {
                default:
                    if (isdigit(*cp)) {
                        state = DIGIT;
                    }
                    else {
                        return NOTFLOATING; 
                    }
                    break;
            }
            break;
        case DIGIT:
            switch (*cp) {
                case 'f':
                case 'F':
                    state = F_END;
                    break;
                case 'l':
                case 'L':
                    state = L_END;
                    break;
                case '\0':
                    return TYPE_DOUBLE;
                default:
                    if (isdigit(*cp)) {
                        state = DIGIT;  
                    }
                    else {
                        return NOTFLOATING;
                    }
            }
            break;
        case F_END:
            switch (*cp) {
                case '\0':
                    return TYPE_FLOAT;
                    break;
                default:
                    return NOTFLOATING;
            }
            break;
        case L_END:
            switch (*cp) {
                case '\0':
                    return TYPE_LDOUBLE;
                default:
                    return NOTFLOATING;
            }
            break;
    }
    cp++;
}

}

Also, with my code set up as it is, if I have a return statement, I don't need a break statement do I? Thanks.

Edited to add full code and clarification.

+6  A: 

I've only skimmed your code, but...

So, near the top you have this:

while (*cp != '\0')

Then inside that loop you have a bunch of these:

switch (*cp)
{
   // snip
case '\0':
   // snip
}

Naturally these case labels are not going to get executed, because if *cp is 0 the condition *cp != '\0' is going to evaluate to false and the loop body will not execute.

asveikau