Как указано в комментариях, это гораздо легче отладить как оператор switch.Я преобразовал его в переключатель, и проблемы с окончательными условиями if / else исчезли.
Я также использую CLion на Mac и видел предупреждения, которые вы видели.
Несмотря на вышеприведенные комментарии, ваш код обрабатывает стиль c '/ * .... * / commentsправильно.
Я думаю, что полезно сообщить людям, что это препроцессор, который просто удаляет комментарии c старого стиля /*..*/
, а не //...
из кода, а затем выдает раздетый код.
Конечный автомат НАМНОГО проще читать как оператор switch, а также легче отлаживать.
Обратите внимание, что в одном месте вы проверяли один из двух символов, что позволило использовать стиль перехода в одном изоператоры switch.
Иногда, когда легче написать код более «просто», чем выяснить, почему компилятор считает, что условие всегда будет выполнено, лучше всего следовать рекомендациям и упрощать.Надеюсь, что это нормально для ваших целей.
Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.
#include <stdio.h>
const char CODE = 0;
const char START_COMMENT = 1;
const char END_COMMENT = 2;
const char COMMENT = 3;
const char INQUOTE = 4;
// Preprocessor which discards comments
int main() {
int c;
char state = CODE;
while (EOF != (c = getchar())) {
switch (state) {
case CODE:
switch (c) {
case '/': // If we are in a comment, we will strip this section of the code
// check if this is the start of a comment:
state = POTENTIAL_COMMENT;
break;
case '"':
case '\'':
state = INQUOTE;
putchar(c);
break;
default:
putchar(c);
}
break;
case INQUOTE:
if (c == '"' || c == '\'') {
state = CODE;
}
putchar(c);
break;
case POTENTIAL_COMMENT:
switch (c) {
case '*': // We saw the '/', so now we se the '*' and we are in a comment, just eat the char
state = COMMENT;
break;
case '/':
state = LINE_COMMENT;
break;
default:
putchar('/'); // we saw a '/' before, but it wasn't really the start of a comment, so put the '/' back and the current char
putchar(c);
state = CODE;
}
case COMMENT:
if (c == '*') {
state = END_COMMENT;
}
break;
case LINE_COMMENT:
if (c == '\n')
state = CODE;
break;
case END_COMMENT:
if (c == '/') {
state = CODE;
} else
state = COMMENT;
}
}
}