Проверка конца строки в операторе switch - PullRequest
2 голосов
/ 15 февраля 2010

Я пишу программу, которая в основном проверяет, является ли число типом float, double или long double для назначения, используя операторы switch и конечный автомат. Я перебираю свою программу, и она доходит до конца, за исключением того, что, кажется, не распознает терминатор строки '\ 0'. Поэтому мне было интересно, правильна ли эта часть моего кода. Я включил весь код, но с вводом, таким как 0.0F, он полностью переходит в состояние F_END, а затем не возвращает TYPE_FLOAT, а вместо этого возвращает NOTFLOATING, и я не вижу, почему он не входит в регистр \ 0 ': оператор.

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++;
}

}

Кроме того, с моим кодом, настроенным как есть, если у меня есть оператор return, мне не нужен оператор break, не так ли?

Отредактировано для добавления полного кода и пояснения.

1 Ответ

7 голосов
/ 15 февраля 2010

Я только просмотрел ваш код, но ...

Итак, около вершины у вас есть это:

while (*cp != '\0')

Тогда внутри этого цикла у вас есть куча таких:

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

Естественно, эти метки регистра не будут выполняться, потому что если *cp равно 0, условие *cp != '\0' будет оценено как ложное, и тело цикла не будет выполнено.

...