搬运自k&r习题解答:
/*
* delete comment in C
*/
#include
#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 (rick@ricken.demon.co.uk)
******************************************************/
#include
#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
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
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 */
/*/
** 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
#definePROGRAM0
#defineBEGIN_COMMENT1
#defineCOMMENT2
#defineEND_COMMENT3
#defineQUOTE4
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);
}
elseputchar(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);
}
elsestate = 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;
}