Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除注释的C程序_C - Fatal编程技术网

删除注释的C程序

删除注释的C程序,c,C,这是我第一次发帖,所以我为糟糕的格式和/或任何不合理的问题道歉 因此,我已经在“删除评论”项目上工作了一段时间,取得了一些进展,但进展甚微。我是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;
}
我最终得到以下结果: 一些东西

some* stuff 

some**/tuff 

"some /* crazy */ stuff " 

some* stuff 

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

您的描述重点是在流上操作和在缓冲区上操作之间的区别。在C和Java中,这两种技术都是可能的

在这里,您的任务是在流的情况下完成工作,即您不能“向前看”也不能“向后写”-您所能做的就是检索下一个字符,在适当的情况下更新一些变量,并决定是否输出该字符

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

要开始,您至少需要存储以下内容:

some/* crazy */stuff
some/* crazy */ stuff
some/*crazy /*crazy*/*/stuff
"some /* crazy */ stuff "
some/* "crazy" */ stuff
some/* crazy stuff
  • 无论你是否在评论中
  • 如果您不在评论中,那么您是否只是阅读了
    /

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

好的,解决这类问题的通常方法是。所以,只需确定状态数,并根据当前状态确定下一个字母将如何影响状态。类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();
}
/#定义(CRT)安全(NO)警告
#包括
#包括
//#包括
#包括
typedef枚举状态{
密码
开始,
星光大道,
议论
}国家;
void main(){
文件*input=NULL;
字符c;
国家;
状态=代码;
输入=fopen(“C:/C/code.txt”、“r”);
如果(输入==NULL){
退出(退出失败);
}
而(fscanf(输入,“%c”,&c)==1){
开关(c){
案例“/”:
开关(状态){
案例代码:
状态=散列\开始;
打破
案例之星(完)
//这里有点难看,但需要较少的状态。您可以省略阅读下一步
//如果使用更多的状态
fscanf(输入,“%c”、&c);
状态=代码;
打破
}
打破
案例“*”:
开关(状态){
案例哈希表开始:
状态=评论;
打破
案例评论:
状态=星端;
打破
}
打破
违约:
if(state==HASH\u START){
状态=代码;
}
}
如果(状态==代码){
printf(“%c”,c);
}
}
//_getch();
}
此代码仅删除/**/。写出更大的图表和完整的代码。

#包括
#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;
}
#如果0 说明: 通过从标准输入中输入C源来删除注释。 //删除换行符(换行符保留)的步骤 /**/允许嵌套(标准不允许) 也替换为单个空间(标准要求) #恩迪夫 内部主(空){ 文件*fp=stdin; int ch,chn; int nest_level=0; #如果0 在\u范围内\u注释:/*此*/ 在注释中://this 在字符串中:“this” 在字符常量中:“” #恩迪夫 枚举{none,in_line_comment,in_range_comment,in_string,in_char_constant}状态; 状态=无; 而(EOF!=(ch=fgetc(fp))){ 开关(状态){ 第行注释中的案例: 如果(ch='\n'){ 状态=无; putchar(ch); } 持续 案例范围注释: 如果(ch=='*'){ chn=fgetc(fp); 如果(chn=='/'){ 如果(--nest_level==0){ 状态=无; putchar(“”); } 持续 } ungetc(chn,fp); }else if(ch=='/')){ chn=fgetc(fp); 如果(chn=='*'){ ++巢穴水平; 持续 } ungetc(chn,fp); } 持续 字符串中的大小写: 如果(ch='\\'){ putchar(ch); chn=fgetc(fp); 如果(chn==“”){ putchar(chn); 持续 } ungetc(chn,fp); }否则{ 如果(ch==“”) 状态=无; putchar(ch); } 持续 _char_常量中的大小写: 如果(ch='\\'){ putchar(ch); chn=fgetc(fp); 如果(chn=='\''){ putchar(chn); 持续 } ungetc(chn,fp); }否则{ 如果(ch='\'') 状态=无; putchar(ch); } 持续 案例无: 开关(ch){ 案例“/”: 如果('/'==(chn=fgetc(fp))){ 状态=行内注释; 持续 }else如果('*'==chn){ 状态=范围内注释; ++巢穴水平; 持续 }否则 ungetc(chn,fp); putchar(ch); 打破 案例'':