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