删除评论的C程序

时间:2014-09-16 04:28:15

标签: c

这是我第一次发帖,所以我为糟糕的格式或任何不合理的问题道歉。

所以我一直在研究"删除评论"程序已经有一段时间了,取得了很大的进步。我是C的新手,所以我用一些基本的功能和技巧来写它。代码的输入文件不需要读取任何函数,而是使用<在终端。

我使用的文本文件包含以下内容:

some/* crazy */stuff
some/* crazy */ stuff
some/*crazy /*crazy*/*/stuff
"some /* crazy */ stuff "
some/* "crazy" */ stuff
some/* crazy stuff

测试不同的评论格式。 我到目前为止的代码是:

#include <stdio.h>
#define IN_COMMENT 1

int main(int argc, char **argv)
{
    int c;

    while ((c=getchar())!=EOF)
    {
        if(c=='/'&&getchar()=='*')
        {
            while(c!='*' && getchar()!='/')
            {
                c = " ";
                c= getchar();

            }

        }


        if(c=='"')
        {
            c=getchar();
            while(c!='"')
            {
                putchar(c);
                c=getchar();
            }
            putchar(c);
        }
    }
putchar(c);
    printf("done.\n");
    return 0;
}

问题是我无法找到一种方法来设置一个条件,当条件开始但是从未关闭时,会打印出错误消息,例如(某些/ *疯狂的东西)< / p>

另一个问题是我似乎无法找到当我运行程序并输入文本文件时省略*的错误,所以当我输入时:

some/* crazy */stuff
some/* crazy */ stuff
some/*crazy /*crazy*/*/stuff
"some /* crazy */ stuff "
some/* "crazy" */ stuff

我最终获得以下内容:     一些*东西

some* stuff 

some**/tuff 

"some /* crazy */ stuff " 

some* stuff 

我无法找到解决这两个问题的方法。教授通过定义不同的状态提出了一种不同的编写程序的方法,但是当我尝试它时,它更令人困惑。

3 个答案:

答案 0 :(得分:0)

您的描述侧重于在上操作和在缓冲区上操作之间的区别。在C和Java中,任何一种技术都是可行的。

在这里,你的任务是在流动的情况下完成工作,即你不能&#34;展望未来&#34;你不能倒退#34; - 您所能做的就是检索下一个字符,在适当的时候更新一些变量,然后决定是否输出该字符。

这称为状态机;你的主循环将读取一个字符,然后根据变量的状态采取不同的操作。

为了帮助您入门,您需要至少存储以下内容:

  • 您是否在发表评论
  • 如果您不在评论中,那么您是否只是阅读/

例如,如果设置了后一种状态并且您得到'*',那么您将设置前一种状态(并重置后者)。

答案 1 :(得分:0)

通常,解决此类问题的方法是FSM。因此,由于当前状态,只需创建多个状态并确定每个下一个字母将如何影响状态。像Smth一样

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//#include <conio.h>
#include <string.h>

typedef enum states {
    CODE,
    HASH_START,
    STAR_END,
    COMMENT
} states;

void main() {
    FILE *input = NULL;
    char c;
    states state;

    state = CODE;
    input = fopen("C:/c/code.txt", "r");
    if (input == NULL) {
        exit(EXIT_FAILURE);
    }

    while (fscanf(input, "%c", &c) == 1) {
        switch (c) {
        case '/' :
            switch (state) {
            case CODE: 
                state = HASH_START;
                break;
            case STAR_END:
                //a bit ugly here, but require less states. You can omit read next
                //if use more states
                fscanf(input, "%c", &c);
                state = CODE;
                break;
            }
            break;
        case '*' :
            switch (state) {
            case HASH_START:
                state = COMMENT;
                break;
            case COMMENT:
                state = STAR_END;
                break;
            }
            break;
        default:
            if (state == HASH_START) {
                state = CODE;
            }
        }
        if (state == CODE) {
            printf("%c", c);
        }
    }

    //_getch();
}

此代码仅删除/ ** /。写出更大的图表和完整的代码。

答案 2 :(得分:0)

#include <stdio.h>

#if 0
Description :
To delete a comment by entering the C source from standard input.
// To delete a line break up (newline remain)
/**/ To allow the nest (standard does not allow)
also replaced with a single space(The request by the standard)
#endif

int main(void){
    FILE *fp = stdin;
    int ch, chn;
    int nest_level=0;
#if 0
in_range_comment : /* this */
in_line_comment  : //this
in_string : "this"
in_char_constnt : ' '
#endif
    enum { none, in_line_comment, in_range_comment, in_string, in_char_constant } status;

    status = none;
    while(EOF!=(ch=fgetc(fp))){
        switch(status){
        case in_line_comment :
            if(ch == '\n'){
                status = none;
                putchar(ch);
            }
            continue;
        case in_range_comment :
            if(ch == '*'){
                chn = fgetc(fp);
                if(chn == '/'){
                    if(--nest_level == 0){
                        status  = none;
                        putchar(' ');
                    }
                    continue;
                }
                ungetc(chn, fp);
            } else if(ch == '/'){
                chn = fgetc(fp);
                if(chn == '*'){
                    ++nest_level;
                    continue;
                }
                ungetc(chn, fp);
            }
            continue;
        case in_string :
            if(ch == '\\'){
                putchar(ch);
                chn = fgetc(fp);
                if(chn == '"'){
                    putchar(chn);
                    continue;
                }
                ungetc(chn, fp);
            } else {
                if(ch == '"')
                    status = none;
                putchar(ch);
            }
            continue;
        case in_char_constant :
            if(ch == '\\'){
                putchar(ch);
                chn = fgetc(fp);
                if(chn == '\''){
                    putchar(chn);
                    continue;
                }
                ungetc(chn, fp);
            } else {
                if(ch == '\'')
                    status = none;
                putchar(ch);
            }
            continue;
        case none :
            switch(ch){
            case '/':
                if('/' == (chn = fgetc(fp))){
                    status = in_line_comment;
                    continue;
                } else if('*' == chn){
                    status = in_range_comment;
                    ++nest_level;
                    continue;
                } else
                    ungetc(chn, fp);
                putchar(ch);
                break;
            case '"':
                status = in_string;
                putchar(ch);
                break;
            case '\'':
                status = in_char_constant;
                putchar(ch);
                break;
            default:
                putchar(ch);
            }
        }
    }

    return 0;
}