/* * delete comment in C */ #include<stdio.h> #define normal 0 void rcomment(int c); void in_comment(void); void echo_quote(int c); main() { int c; while ((c = getchar()) != EOF) rcomment(c); return 0; } void rcomment(int c) { int d; if (c == '/') if ((d = getchar()) == '*') in_comment(); else if (d == '/') { putchar(c); rcomment(d); } else { putchar(c); putchar(d); } else if (c == '\'' || c == '"') echo_quote(c); else putchar(c); } void in_comment(void) { int c,d; c=getchar(); d=getchar(); while(c!='*' || d!='/'){ c=d; d=getchar(); } } void echo_quote(int c) { int d; putchar(c); while((d=getchar())!=c){ putchar(d); if(d=='\\') putchar(getchar()); } putchar(d); }
书中答案rcomment函数中的
else if (d == '/') { putchar(c); rcomment(d); }这个语句看了好久没没明白什么意思,测试程序的话,不处理'//'注释,只删除/* */之间的,不敢确定是不是答案有问题。
估计这是原本应该删除//到换行之间的注释的,若是这样,这个语句应改为:
else if (d == '/') { while(getchar()!='\n'); }
不知道机械工业的那本中文答案是否可靠,在网上搜到一个英文版本答案,皮皮书屋可以下到chm版的,大概500多页,感觉这个答案比较好,有的题目有好几个解决办法,应对的情况也更详细。
再贴几个:
From Rick Dearman Now handles "/* comment in string */" correctly, but does not remove the comment from return /* comment inside return statement */ 0; /****************************************************** "Write a program to remove all comments from a C program. Don't forget to handle quoted strings and character constants properly. C comments do not nest." Author: Rick Dearman ([email protected]) ******************************************************/ #include <stdio.h> #define MAXLINE 1000 /* max input line size */ char line[MAXLINE]; /*current input line*/ int getline(void); /* taken from the KnR book. */ int main() { int in_comment,len; int in_quote; int t; in_comment = in_quote = t = 0; while ((len = getline()) > 0 ) { t=0; while(t < len) { if( line[t] == '"') in_quote = 1; if( ! in_quote ) { if( line[t] == '/' && line[t+1] == '*') { t=t+2; in_comment = 1; } if( line[t] == '*' && line[t+1] == '/') { t=t+2; in_comment = 0; } if(in_comment == 1) { t++; } else { printf ("%c", line[t]); t++; } } else { printf ("%c", line[t]); t++; } } } return 0; } /* getline: specialized version */ int getline(void) { int c, i; extern char line[]; for ( i=0;i<MAXLINE-1 && ( c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if(c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i; } From Ben Pfaff This version is a bugfix for the code var/'\2' /* K&R2 1-23: Write a program to remove all comments from a C program. Don't forget to handle quoted strings and character constants properly. C comments do not nest. This solution does not deal with other special cases, such as trigraphs, line continuation with \, or <> quoting on #include, since these aren't mentioned up 'til then in K&R2. Perhaps this is cheating. Note that this program contains both comments and quoted strings of text that looks like comments, so running it on itself is a reasonable test. It also contains examples of a comment that ends in a star and a comment preceded by a slash. Note that the latter will break C99 compilers and C89 compilers with // comment extensions. Interface: The C source file is read from stdin and the comment-less output is written to stdout. **/ #include <stdio.h> int main(void) { #define PROGRAM 0 #define SLASH 1 #define COMMENT 2 #define STAR 3 #define QUOTE 4 #define LITERAL 5 /* State machine's current state, one of the above values. */ int state; /* If state == QUOTE, then ' or ". Otherwise, undefined. */ int quote; /* Input character. */ int c; state = PROGRAM; while ((c = getchar()) != EOF) { /* The following cases are in guesstimated order from most common to least common. */ if (state == PROGRAM || state == SLASH) { if (state == SLASH) { /* Program text following a slash. */ if (c == '*') state = COMMENT; else { putchar('/'); state = PROGRAM; } } if (state == PROGRAM) { /* Program text. */ if (c == '\'' || c == '"') { quote = c; state = QUOTE; putchar(c); } else if (c == "/*"[0]) state = SLASH; else putchar(c); } } else if (state == COMMENT) { /* Comment. */ if (c == "/*"[1]) state = STAR; } else if (state == QUOTE) { /* Within quoted string or character constant. */ putchar(c); if (c == '\\') state = LITERAL; else if (c == quote) state = PROGRAM; } else if (state == SLASH) { } else if (state == STAR) { /* Comment following a star. */ if (c == '/') state = PROGRAM; else if (c != '*') state = COMMENT; } else /* state == LITERAL */ { /* Within quoted string or character constant, following \. */ putchar(c); state = QUOTE; } } if (state == SLASH) putchar('/' //**/ 1); return 0; } /* Local variables: compile-command: "checkergcc -W -Wall -ansi -pedantic knr123-0.c -o knr123-0" End: */ From Lew Pitcher /* Lew Pitcher <[email protected]> */ /*/ ** derem - remove C comments ** ** (attempt to solve K&R Exercise 1-22) ** ** As I only have v1 copy of K&R, I cannot ** be sure what is covered in K&R ANSI chapter 1. ** So, I restrict myself to the components covered ** in K&R v1 chapter 1, but modified for requisite ANSI ** features (int main() and return value). ** ** Components covered in v1 K&R chapter 1 include: ** while (), for (), if () else ** getchar(), putchar(), EOF ** character constants, character escapes ** strings ** array subscripting ** ** Not directly covered are ** string subscripting ( "/*"[0] ) ** initializers ( int state = PROGRAM; ) **/ /*/*/ #include <stdio.h> #define PROGRAM 0 #define BEGIN_COMMENT 1 #define COMMENT 2 #define END_COMMENT 3 #define QUOTE 4 int main(void) { int this_char, quote_char; int state; state = PROGRAM; while ((this_char = getchar()) != EOF) { if (state == PROGRAM) { if (this_char == '/') state = BEGIN_COMMENT; else if ((this_char == '"') || (this_char == '\'')) { state = QUOTE; putchar(quote_char = this_char); } else putchar(this_char); } else if (state == BEGIN_COMMENT) { if (this_char == '*') state = COMMENT; else { putchar('/'); /* for the '/' of the comment */ if (this_char != '/') { state = PROGRAM; putchar(this_char); } else state = COMMENT; /* stuttered */ } } else if (state == QUOTE) { putchar(this_char); if (this_char == '\\') putchar(getchar()); /* escaped character */ else if (this_char == quote_char) state = PROGRAM; } else if (state == COMMENT) { if (this_char == '*') state = END_COMMENT; } else if (state == END_COMMENT) { if (this_char == '/') state = PROGRAM; else if (this_char != '*') /* stuttered */ state = COMMENT; } } return 0; }