状态机处理文本

/*
**删除C/C++源代码中的注释
*/
#include <stdio.h>
int main( int argc, char *argv[] )
{
	//定义各种状态
	enum{NONE,PRE_LINE,LINE,ALL,PREEND_ALL,ALL_END} state = NONE;
	char *fileinput, *fileoutput;
	FILE *fpinput, *fpoutput;
	int ch;

	if(argc != 3){
		printf("none of input and output file!");
		return -1;
	}
	//参数1为输入文件名,参数2为输出文件名
	fileinput = argv[1];
	fileoutput = argv[2];

	if((fpinput = fopen(fileinput,"r")) == NULL){
		printf("Open input file error!");
		return -1;
	}

	if((fpoutput = fopen(fileoutput,"w")) == NULL){
		printf("Open input file error!");
		return -1;
	}
	while( (ch = fgetc(fpinput)) != EOF)      //循环读取文件中的字符
	{
		switch(ch)
		{
		case '/':
			if(state == NONE)
				state = PRE_LINE;
			else
			{
				if(state == PRE_LINE)
					state = LINE;
				else if(state == PREEND_ALL)
					state = ALL_END;
				
			}
			break;
		case '*':
			if(state == PRE_LINE)
				state = ALL;
			else
			{
				if(state == ALL)
					state = PREEND_ALL;
			}
			break;
		case '\n':
			if(state == LINE)
				state = NONE;
			break;
		default:
			if(state == ALL_END)
				state = NONE;
		}
		if(state == NONE)
			putc(ch,fpoutput);
	}
	putc(EOF,fpoutput);       //给输出文件尾加EOF结束标志

	fclose(fpoutput);
	fclose(fpinput);
}


 

以上代码用enum定义了一些状态,其中,NONE表示非注释状态,PRE_LINE表示在NONE状态下遇到'/'字符,LINE表示PRE_LINE下遇到再'/'字符,ALL表示PRE_LINE状态下遇到'*'字符,PREEND_ALL表示ALL状态下遇到'*'字符,ALL_END表示PREEND_ALL状态下遇到'/'字符。
通过这些状态就可以很轻松的知道当前字符是否注释,不是注释就复制到输出文件中。其实很多文本文件的处理,像删掉含有某一字符串的行,查找某字符串,甚至高级点的像ini文件、xml文件都可以用状态机实现。


注:其中ch变量声明为int类型是因为EOF为整形,如果ch为char型,当ch和EOF的低位相等时,一比较的话,就会跳出循环,而实际上我们的文件还没有结束,所以防止这类错误,声明ch为int型。

-------本人菜鸟一只,如有不足,望大牛指出^_^

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值