C 条件总是正确的。我的代码中有Bug,还是IDE中有Bug?

C 条件总是正确的。我的代码中有Bug,还是IDE中有Bug?,c,C,我一直在做一些“C编程语言”(第二版)的练习,我现在在1-23,在那里你需要开发一个去掉注释的程序 这就是我迄今为止所做的: #include <stdio.h> #define CODE 0 #define START_COMMENT 1 #define END_COMMENT 2 #define COMMENT 3 #define INQUOTE 4 /* this is a test */ /* this is a *** comment maybe / but stil

我一直在做一些“C编程语言”(第二版)的练习,我现在在1-23,在那里你需要开发一个去掉注释的程序

这就是我迄今为止所做的:

#include <stdio.h>

#define CODE 0
#define START_COMMENT 1
#define END_COMMENT 2
#define COMMENT 3
#define INQUOTE 4

/* this is a test */

/* this is a *** comment maybe / but still testing */

main() {
    char c;
    char state=CODE;
    while ((c = getchar()) != EOF) {

        if(state == CODE) {
            if (c == '/') {
                state = START_COMMENT; /* this works? */
            }
            else if (c == '"' || c == '\'') {
                state = INQUOTE;
                putchar(c);
            }
            else {
                putchar(c);
            }
        }
        else if(state == INQUOTE) {
            if (c == '"' || c == '\'') {
                state = CODE;
                putchar(c);
            }
            else {
                putchar(c);
            }
        }
        else if(state == START_COMMENT) {
            if (c == '*') {
                state = COMMENT;
            }
            else {
                putchar('/');
                putchar(c);
                state = CODE;
            }
        }
        else if(state == COMMENT) {
            if (c == '*') {
                state = END_COMMENT;
            }
        }
        else if(state == END_COMMENT) {
            if (c == '/') {
                state = CODE;
            }
            else
                state = COMMENT;
        }
    }
}
尽管有这句话,该计划似乎工作到目前为止


这条线的计算结果总是真的吗?如果是,为什么?因为我看不出它有什么问题。

如注释中所述,作为switch语句进行调试要容易得多。我将其转换为一个开关,最终的if/else条件问题消失了

我还在mac上使用CLion,看到了您看到的警告

尽管有上述注释,您的代码仍处理c样式“/*../评论正确

我认为让人们知道这是一个预处理器是很有帮助的,它可以简单地从代码中剥离旧式的c注释
/*.*/
而不是
/…
,然后将剥离的代码取出

状态机作为switch语句更容易阅读,也更容易调试

注意,在一个地方,您检查了两个字符中的一个,这允许在其中一个switch语句中使用fallthrough样式

有时,如果编写代码更“简单”,而不是找出编译器认为某个条件始终为真的原因,那么最好遵循最佳实践并进行简化。希望这对你的目的是好的

如果你有任何问题,请告诉我

#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;
        }
    }
}
#包括
常量字符代码=0;
const char START_COMMENT=1;
const char END_COMMENT=2;
const char COMMENT=3;
const char INQUOTE=4;
//丢弃注释的预处理器
int main(){
INTC;
字符状态=代码;
而(EOF!=(c=getchar()){
开关(状态){
案例代码:
开关(c){
案例“/”://如果我们在注释中,我们将删除这段代码
//检查这是否是评论的开始:
状态=潜在的注释;
打破
案例'':
案例'\'':
state=INQUOTE;
普查尔(c);
打破
违约:
普查尔(c);
}
打破
案例引述:
如果(c=''''''.| c==''\''){
状态=代码;
}
普查尔(c);
打破
案例潜在性意见:
开关(c){
案例“*”://我们看到了“/”,所以现在我们使用“*”,我们在一个注释中,只吃这个字符
状态=评论;
打破
案例“/”:
状态=行注释;
打破
违约:
putchar(“/”);//我们以前看到过一个“/”,但它实际上不是注释的开头,所以请将“/”放回原处,并将当前字符放回原处
普查尔(c);
状态=代码;
}
案例评论:
如果(c=='*'){
状态=结束注释;
}
打破
案例行注释:
如果(c=='\n')
状态=代码;
打破
案例结束注释:
如果(c=='/')){
状态=代码;
}否则
状态=评论;
}
}
}

关于:
案例注释:if(c=='*'){state=END_COMMENT;}
这不适用于“doxygen”和类似注释。也就是说,
/***
不适用于三角图,也不适用于:
/***我的评论…
评论不适用于扩展讨论或调试会话;这段对话已经结束。当你被要求提供更多信息或想澄清一些事情时,你应该编辑问题。其他对如何改进代码有反馈或建议的人应该给出答案。
#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;
        }
    }
}