/*
**删除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型。
-------本人菜鸟一只,如有不足,望大牛指出^_^