去掉C/C++源程序中的注释

一道题目,输入是一个正确的C/C++源程序,输出是将所有注释去掉之后的程序。不细想觉得很简单,字符串搜索,找到//后再找一个回车,删掉,找到/*后再找一个*/,删掉,还有什么好做的,太简单了。

给个测试例子:

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()

{

 cout<<"line 1 // hello"<<endl; // line 1
 cout<<"line 2 /* haha~ */"<<endl; // line 2
 cout<<"line 3 \" /* hehe */"<<endl; /* line 3 */
 /* ********\\\\\\\\\\/////////********
 this is test program
 this is test program
 this is test program
 */
 return 0;

}

这是正确的C++程序,它的输出要是:

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()

{

 cout<<"line 1 // hello"<<endl;
 cout<<"line 2 /* haha~ */"<<endl;
 cout<<"line 3 \" /* hehe */"<<endl;
 
 return 0;

}

哇,这么一来想想就觉得复杂,字符串,先要找到字符串,字符串里的不算,字符串里还有转义符。。。

用状态机做会不会很方便,输入集中比较特殊的就这几个:/,*,",\,关键是在它的构造,在本子上画个表,纵向是表示状态,横向表示特殊的输入,表中的值就是状态的变化,再在旁边记录各个状态的含义,它大概是这样:

   \输入  /   *   "   \   回车  其它
状态
0           1   0   5   0    0      0
1
2
...

0: 正在分析
1:读到第一个/
2:读完第二个/,"//...
3:读到 "/*...
4:读到 "/*...*
5:读到第一个"
6:读到字符串里的转义符 "...\
7:找到注释

0和7是等价的状态,但是可以用7状态做些特别的事情,比如这个时候删除刚找到的注释等。最后的程序如下,输入输出还是用C的文件比较方便:

#include "stdio.h"
#include "string"

char fsm[8][128];

void initfsm()

{

 const int line_len=sizeof(char)*128;
 memset(fsm[0],0,line_len);
 memset(fsm[1],0,line_len);
 memset(fsm[2],2,line_len);
 memset(fsm[3],3,line_len);
 memset(fsm[4],3,line_len);
 memset(fsm[5],5,line_len);
 memset(fsm[6],5,line_len);
 memset(fsm[7],0,line_len);
 fsm[0]['/']=1;
 fsm[0]['"']=5;
 fsm[1]['/']=2;
 fsm[1]['*']=3;
 fsm[1]['"']=5;
 fsm[2]['\n']=7;
 fsm[3]['*']=4;
 fsm[4]['/']=7;
 fsm[4]['*']=4;
 fsm[5]['"']=0;
 fsm[5]['\\']=6;
 fsm[7]['/']=1;
 fsm[7]['"']=5;

}

 

 

 

int main()

{

 int state=0;
 char c;
 std::string s;
 FILE *fin=fopen("e:\\in.txt","r");
 FILE *fout=fopen("e:\\out.txt","w");
 initfsm();
 while(fscanf(fin,"%c",&c)!=EOF)
 {
    state=fsm[state][c];
    s+=c;
    switch(state)
    {
      case 0:
         fprintf(fout,"%s",s.c_str());
         s="";
         break;
      case 7:
         s="";
         if(c=='\n')
         {
            fputc(c,fout);
         }
         break;
    }
 }
 fclose(fin);
 fclose(fout);
 return 0; 

posted @ 2010-07-06 02:27  杨杨ye  阅读(3418)  评论(0编辑  收藏  举报