免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9060 | 回复: 11
打印 上一主题 下一主题

去掉c代码中的注释的方法(汇总) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-24 21:45 |只看该作者 |倒序浏览
原始讨论贴见:
http://bbs.chinaunix.net/viewthread.php?tid=846353&extra=page%3D1

http://bbs.chinaunix.net/viewthread.php?tid=846682&extra=page%3D1

http://bbs.chinaunix.net/viewthread.php?tid=846685&extra=page%3D1

感谢大家的热情参与!我把符合基本要求的方法统一汇总到这里,方便大家分析和比较各种方法的优劣。

对于方法需要满足的基本要求,目前暂定为能够处理以下5种形式的c语言注释:

  1. 1.  /* aaaaaaaaaaaaaaaaaaaaaaaaa
  2.        bbbbbbbbbbbbbbbbbbbbbbbbb
  3.        ccccccccccccccccccccccccc */
  4.    
  5. 2.  /* ddddddddddddddddddddddddd */
  6.    
  7. 3.  int foo; /* eeeeeeeeeeeeeeeee */
  8.    
  9. 4.  /* ffffffffffffffff */  int bar;
  10.    
  11. 5.  int foobar; /* gggggggggggggggg
  12.                    hhhhhhhhhhhhhhhh
  13.                    iiiiiiiiiiiiiiii */
复制代码


大家提出的方法我会尽快验证,已经通过验证的方法如下(按方法大类组织):

【雨丝风片】,awk脚本:

  1. BEGIN { del = 0 }
  2. /\/\*.*\*\// { sub(/\/\*.*\*\//, "") }
  3. /\/\*/ { del = 1; sub(/\/\*.*$/, ""); if (!match($0, /^ *$/)) print }
  4. /\*\// { del = 0; next }
  5. /^ *$/ { next }
  6. del == 0 { print }
复制代码



【congli】,awk脚本:

  1. BEGIN { del = 0; d = 0 }
  2. /\/\*.*\*\// { sub(/\/\*.*\*\//,"") }
  3. /.*\/\*/ { sub(/\/\*.*\*\//,"") }
  4. /^\/\*/ { del = 1; d=1 }
  5. {if (d==1) { del = 1 } else { del = 0}}
  6. /\*\// { if (d==1) { d=0 ; next } }
  7. /.*\/\*.*/ { sub(/\/\*.*/,""); d=1 }
  8. /^ *$/ { next }
  9. del == 0 { print }
复制代码



【waker】,awk:

  1. awk 'BEGIN{RS="/\*|\*/"} NR%2'  foo.c
复制代码



【woodie】,awk:
  1. awk -vRS='/\\*|\\*/' -vORS="" '!c;RT=="/*"{c++}RT=="*/"{c--}'
复制代码



【woodie】,awk:
  1. awk -vRS='/\\*|\*/' -vORS="" '{sub(/\/\/.*\n/, "")}!c;RT=="/*"{c++}RT=="*/"{c--}'
复制代码



【awk就是awp加ak】,awk:

  1. awk '
  2. function clearComment(){

  3.         if ($0~/\/\*/){

  4.                 if ($0~/\*\//) sub(/\/\*.*\*\//, "");
  5.                 else sub(/\/\*.*/, "");
  6.                 print;

  7.                 while (getline == 1 && !($0~/\*\//));
  8.                
  9.                 sub(/.*\*\//, "");


  10.         } else if ($0~/\/\//) sub(/\/\/.*/, "");

  11.         if ($0~/\/\*/) clearComment();
  12.         else print;
  13. }

  14. {
  15.         clearComment();
  16. }' foo.c
复制代码



【awk就是awp加ak】,sed:

  1. sed '
  2.         s%//.*%%

  3.         /\/\*/{
  4.         :next
  5.                 N
  6.                 /\*\//!b next
  7.                 s%/\*.*\*/%^M%
  8.         }
  9.         /\/\*/b next
  10. ' foo.c
复制代码



【qqq112233g】,sed:

  1. sed -n 'H;${g;s#/\*[^*]*\*/##g;s/\n *\n//g;p}' foo.c
复制代码



【lovesaka】,perl:

  1. perl -ne 'if(/\/\*/&&/\*\//||/^$/){print if(s/\/\*.*\*\/// && !/^\s+$/);next}elsif(/\/\*/){$flag=1;print if(s/\/\*.*$// && !/^\s+$/); next}elsif(/\*\//){$flag=0;print if(s/^.*\*\/// && !/^\s+$/);next}else{next if($flag);print}' foo.c
复制代码



【windwiny】,perl脚本:

  1. #!/usr/bin/perl -w

  2. # move C/C++ source file all comment
  3. #    CopyError(R) windwiny.  #### NO ANY WARRANTY ####
  4. #
  5. # Usage:
  6. #        mvcommen.pl < aaa.c > bbb.c
  7. #

  8. $cc1=0;        # line comment and \ ended;
  9. $cc2=0; # block comment begin but no end blocked.
  10. while (<>)
  11. {
  12. # aaa // bbb ccc \
  13. # ddd eee \
  14. # fff
  15.         if ($cc1 !=0)
  16.         {
  17.                 if (m/(.*)(\\$)/)
  18.                 {
  19.                         next;
  20.                 }
  21.                 else
  22.                 {
  23.                         $cc1=0;
  24.                         next;
  25.                 }
  26.         }
  27.         if (s/(.*?)(\/\/.*)(\\$)/$1/)
  28.         {
  29.                 print ;
  30.                 $cc1=1;
  31.                 next;
  32.         }
  33.                
  34. # aaa // bbb ccc // ddd /* eee */ ... except above 's case
  35.         s/(.*?)(\/\/.*$)/$1/;        # NOT next

  36. # aaa /* bbb ccc
  37. # ddd eee
  38. # fff */ ggg
  39.         if ($cc2 !=0)
  40.         {
  41. # ? WARRING: disable /* /* */ */'s style comment
  42.                 if (s/(.*?)(\*\/)(.*)/$3/)
  43.                 {
  44.                         print ;
  45.                         $cc2=0;
  46.                         next;
  47.                 }
  48.                 next;
  49.         }
  50. # aaa /* bbb */ ccc
  51.         if (s/(.*?)(\/\*.*?\*\/)(.*)/$1$3/)
  52.         {
  53.                 print ;
  54.                 next;
  55.         }
  56. #   --> join up  #### CAN NOT move above 's if above ####
  57.         if (s/(.*?)(\/\*.*$)/$1/)
  58.         {
  59.                 print ;
  60.                 $cc2=1;
  61.                 next;
  62.         }

  63. # Other case:
  64. # aaa /* bbb
  65. #   ccc */ ddd; /* eee */ or // fff
  66. #   This is too BT,can not moved.  :-(

  67. # default
  68.         print;
  69. }

  70. # vim:ts=4:sts=4:sw=4:cin
复制代码



【Namelessxp】,perl脚本:

  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. $/ = undef;
  5. while (<>){
  6.         $_ =~ s/\/\*.*?\*\///igs;
  7.         $_ =~ s/(\r?\n)+/\n/igs;
  8.         print;
  9. }
  10. exit;
复制代码



【li-jiahuan】,perl:
  1. perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
复制代码



【li-jiahuan】,perl脚本:

  1.     $/ = undef;
  2.     $_ = <>;
  3.     s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|\n+|.[^/"'\\]*)#$2#g;
  4.     print;
复制代码



【mq110】,lex脚本:

  1. %{
  2. #include <stdio.h>
  3. void  comment();
  4. int yywrap()
  5. {
  6.         return 1;
  7. }
  8. %}
  9. %%
  10. "/*"  {comment(); }
  11. .  {printf("%c",yytext[0]);}
  12. %%
  13. void comment()
  14. {
  15.         for(;;)
  16.         {
  17.                 while (input()!='*');
  18.                 if(input()!='/')
  19.                         unput(yytext[yyleng-1]);
  20.                 else
  21.                         return;
  22.         }
  23. }
复制代码


【gvim】,lex脚本:

  1. %{
  2. %}
  3. comment  "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/"
  4. %%
  5. {comment} {  }
  6. %%
复制代码



【emacsnw】,c程序:

  1. /*
  2. * Removes comments from C codes.
  3. */

  4. #include <stdio.h>

  5. typedef enum {
  6.     FA_NORMAL,  /* normal texts     */
  7.     FA_QUOTE,   /* inside a string  */
  8.     FA_META,    /* meta character \ */
  9.     FA_BSLASH,  /* after /          */
  10.     FA_COMMENT, /* inside comments  */
  11.     FA_STAR     /* after *          */
  12. } FA_STATE;

  13. int main(int argc, char *argv[])
  14. {
  15.     FILE *fp;
  16.     int ch;
  17.     FA_STATE state;

  18.     if (argc < 2) {
  19.         fprintf(stderr, "Not enough arguments.\n"
  20.                 "Must specify the C source file.\n");
  21.         exit(-1);
  22.     }
  23.     if ((fp = fopen(argv[1], "r")) == NULL) {
  24.         fprintf(stderr, "Can't open %s.\n", argv[1]);
  25.         exit(-1);
  26.     }
  27.     state = FA_NORMAL;
  28.     while ((ch = fgetc(fp)) != EOF) {
  29.         switch (state) {
  30.         start_over:
  31.         case FA_NORMAL:
  32.             if (ch == '"') {
  33.                 putchar(ch);
  34.                 state = FA_QUOTE;
  35.             } else if (ch == '/')
  36.                 state = FA_BSLASH;
  37.             else
  38.                 putchar(ch);
  39.             break;
  40.         case FA_QUOTE:
  41.             if (ch == '\\') {
  42.                 putchar(ch);
  43.                 state = FA_META;
  44.             } else if (ch == '"') {
  45.                 putchar(ch);
  46.                 state = FA_NORMAL;
  47.             } else
  48.                 putchar(ch);
  49.             break;
  50.         case FA_META:
  51.             putchar(ch);
  52.             state = FA_QUOTE;
  53.             break;
  54.         case FA_BSLASH:
  55.             if (ch == '*')
  56.                 state = FA_COMMENT;
  57.             else {
  58.                 putchar('/'); /* restore the previous ch */
  59.                 state = FA_NORMAL;
  60.                 goto start_over;
  61.             }
  62.             break;
  63.         case FA_COMMENT:
  64.             if (ch == '*')
  65.                 state = FA_STAR;
  66.             break;
  67.         case FA_STAR:
  68.             if (ch == '/')
  69.                 state = FA_NORMAL;
  70.             else if (ch == '*')
  71.                 state = FA_STAR;
  72.             else
  73.                 state = FA_COMMENT;
  74.             break;
  75.         }
  76.     }
  77.     exit(0);
  78. }
复制代码


期待大家继续提出其它的解决方法!

[ 本帖最后由 雨丝风片 于 2006-10-26 08:35 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-10-25 09:38 |只看该作者
顶。

论坛徽章:
0
3 [报告]
发表于 2006-10-25 09:46 |只看该作者
【Namelessxpt】,Perl脚本:




  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. $/ = undef;
  5. while (<>){
  6.         $_ =~ s/\/\*.*?\*\///igs;
  7.         $_ =~ s/(\r?\n)+/\n/igs;
  8.         print;
  9. }
  10. exit;
复制代码



perl xxx.pl input.c > output.c

[ 本帖最后由 Macolex 于 2006-10-25 09:47 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-10-25 18:09 |只看该作者

python version

import sys, re
print re.compile(r'/\*.*?\*/', re.DOTALL).sub('', sys.stdin.read())

论坛徽章:
0
5 [报告]
发表于 2006-10-26 02:13 |只看该作者
那几种是最简单的了。
下面的语句是比较晦涩的。

char * a="aaaaa/* ";

char * b="bbbbb*/";

/*
1234

//*/

/*/

论坛徽章:
0
6 [报告]
发表于 2006-10-26 06:45 |只看该作者
偶来个C的,貌似比perl等还是显得麻烦不少:

  1. /*
  2. * Removes comments from C codes.
  3. */

  4. #include <stdio.h>

  5. typedef enum {
  6.     FA_NORMAL,  /* normal texts     */
  7.     FA_QUOTE,   /* inside a string  */
  8.     FA_META,    /* meta character \ */
  9.     FA_BSLASH,  /* after /          */
  10.     FA_COMMENT, /* inside comments  */
  11.     FA_STAR     /* after *          */
  12. } FA_STATE;

  13. int main(int argc, char *argv[])
  14. {
  15.     FILE *fp;
  16.     int ch;
  17.     FA_STATE state;

  18.     if (argc < 2) {
  19.         fprintf(stderr, "Not enough arguments.\n"
  20.                 "Must specify the C source file.\n");
  21.         exit(-1);
  22.     }
  23.     if ((fp = fopen(argv[1], "r")) == NULL) {
  24.         fprintf(stderr, "Can't open %s.\n", argv[1]);
  25.         exit(-1);
  26.     }
  27.     state = FA_NORMAL;
  28.     while ((ch = fgetc(fp)) != EOF) {
  29.         switch (state) {
  30.         start_over:
  31.         case FA_NORMAL:
  32.             if (ch == '"') {
  33.                 putchar(ch);
  34.                 state = FA_QUOTE;
  35.             } else if (ch == '/')
  36.                 state = FA_BSLASH;
  37.             else
  38.                 putchar(ch);
  39.             break;
  40.         case FA_QUOTE:
  41.             if (ch == '\\') {
  42.                 putchar(ch);
  43.                 state = FA_META;
  44.             } else if (ch == '"') {
  45.                 putchar(ch);
  46.                 state = FA_NORMAL;
  47.             } else
  48.                 putchar(ch);
  49.             break;
  50.         case FA_META:
  51.             putchar(ch);
  52.             state = FA_QUOTE;
  53.             break;
  54.         case FA_BSLASH:
  55.             if (ch == '*')
  56.                 state = FA_COMMENT;
  57.             else {
  58.                 putchar('/'); /* restore the previous ch */
  59.                 state = FA_NORMAL;
  60.                 goto start_over;
  61.             }
  62.             break;
  63.         case FA_COMMENT:
  64.             if (ch == '*')
  65.                 state = FA_STAR;
  66.             break;
  67.         case FA_STAR:
  68.             if (ch == '/')
  69.                 state = FA_NORMAL;
  70.             else if (ch == '*')
  71.                 state = FA_STAR;
  72.             else
  73.                 state = FA_COMMENT;
  74.             break;
  75.         }
  76.     }
  77.     exit(0);
  78. }
复制代码


测试文件

  1. This is a test file containing various C comments:

  2. /* simplest comment ****//////*
  3. /*
  4. * multiple line
  5. * comment
  6. */

  7. " Comments inside a string should /* not */ be deleted."

  8. " How about \" this /* case? " and "this */ case? "

  9. And testing cases from CU posts:

  10. 1.  /* aaaaaaaaaaaaaaaaaaaaaaaaa
  11.        bbbbbbbbbbbbbbbbbbbbbbbbb
  12.        ccccccccccccccccccccccccc */
  13.    
  14. 2.  /* ddddddddddddddddddddddddd */
  15.    
  16. 3.  int foo; /* eeeeeeeeeeeeeeeee */
  17.    
  18. 4.  /* ffffffffffffffff */  int bar;
  19.    
  20. 5.  int foobar; /* gggggggggggggggg
  21.                    hhhhhhhhhhhhhhhh
  22.                    iiiiiiiiiiiiiiii */

  23. And even more:
  24. char * a="aaaaa/* ";

  25. char * b="bbbbb*/";

  26. /*
  27. 1234

  28. //*/

  29. /*/ I don't think this is valid. Should end comments somewhere ****/

  30. Got'em all right?

  31. :)
复制代码


运行结果:

  1. [bohnanza:misc]$ cc -O2 rmcom.c
  2. [bohnanza:misc]$ ./a.out comments.test
  3. This is a test file containing various C comments:

  4. ////

  5. " Comments inside a string should /* not */ be deleted."

  6. " How about \" this /* case? " and "this */ case? "

  7. And testing cases from CU posts:

  8. 1.
  9.    
  10. 2.
  11.    
  12. 3.  int foo;
  13.    
  14. 4.    int bar;
  15.    
  16. 5.  int foobar;

  17. And even more:
  18. char * a="aaaaa/* ";

  19. char * b="bbbbb*/";





  20. Got'em all right?

  21. :)

复制代码

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:56:11
7 [报告]
发表于 2006-11-01 08:10 |只看该作者
C中还允许如下的注释:
/\
* xxxx */

论坛徽章:
0
8 [报告]
发表于 2006-11-11 14:56 |只看该作者
嘿嘿
不知道这样的你们能不能去掉
例1
/* //*/
例2
// /*
/* */

论坛徽章:
0
9 [报告]
发表于 2007-07-11 15:16 |只看该作者
请问怎样去掉:
#if 0
.....
#endif

?
wisefly 该用户已被删除
10 [报告]
发表于 2007-07-23 14:55 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP