2

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?

Edited to add full code and clarification.

4
  • 1
    Not much to go on. Can you add more context? Possible you didn't advance the character after reading the F? And, no... no need for a break statement. Commented Feb 15, 2010 at 0:12
  • What's wrong with atof function? Commented Feb 15, 2010 at 0:16
  • I haven't thought through the full extent of your problem, but this seems like way more code than is necessary. Commented Feb 15, 2010 at 0:20
  • You're missing a } for compound statement...oh wait...I see it, it slipped outside of the code... Commented Feb 15, 2010 at 0:28

1 Answer 1

7

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.