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

http://www.cnblogs.com/yangyangye/articles/1771823.html


一道题目,输入是一个正确的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的文件比较方便:

// deletezhushi.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#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("in.txt","r");
	FILE *fout=fopen("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; 
} 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值