打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
去掉c代码中的注释的方法(汇总)
 原始讨论贴见:
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 编辑 ]
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
SED与AWK学习笔记 - 运维人生
【转】干货分享
sed & awk (1)
Shell下三种遍历文件的方法比较
linux下删除空行的几种方法
awk、sed、等实用实例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服