我先mark一下,周末写。
不过理论上不应该是你说的那样
遇到/*而没有后面的*/,则将/*后面的消除---------------这个是不对的
删除注释,前提应该是你的cpp可以编译,不可能出现这种有/*而没有*/的情况,如果简单粗暴地将/*之后的全部删除,那修改后的文件就不知道错到哪里去了
/************************************************************************
* 本程序需要以dos命令行形式打开,支持txt格式
* file1和file2以绝对路径表示,用法为del.exe oldfile.txt newfile.txt,例如:
* D:\????\Visual Studio 2010\Projects\DelComments\Debug>DelComments.exe e:\BPALTask.txt e:\NewFile.txt
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>#define MAX_BUFF_LEN 1024
#define MAX_FNAME_LEN 256
/*************************************************************************/
//删除文件中的注释,这个文件本身应该没有错误,尤其是引号要匹配,"/*"和"*/"要匹配
//算法大体上应该如下:
//步骤1:读取一行,查找"//",若找到,则删除这一行中"//"后所有的部分
//步骤2:读取一行,查找"/*",若找到,记录pos1,删除pos1到本行末尾,重新读取一行,
//查找"*/", 若找到,记录pos2,删除本行0到pos2之间的部分
//重复步骤1和2//需要考虑的特殊情况有:
//处于双引号中,如"/","*", "//"不计入考虑范围
//处于单引号中,如'/', '*', '//'不计入考虑范围
//"//"与"/"的嵌套关系
/************************************************************************/void DelComments(FILE *pFile, FILE *tempFile)
{
char buff[MAX_BUFF_LEN] = {0};
char *pCur = NULL; //当前字符
char *pNext = NULL; //下一字符
char *sqStart = NULL; //单引号起始位置
char *dqStart = NULL; //双引号起始位置
char *scStart = NULL; //单行注释起始位置
char *dcStart = NULL; //多行注释起始位置
unsigned char len = 0; while (NULL != fgets(buff, MAX_BUFF_LEN, pFile))
{
pCur = buff;
while ('\n' != *pCur)
{
switch (*pCur)
{
case '/':
if (sqStart || dqStart || scStart || dcStart)
{//忽略字符、字符串以及注释中的斜杠
pCur++;
}
else
{
pNext = pCur + sizeof(char);
if ('/' == *pNext)
{//单行注释
dcStart = pCur;
pCur = pNext + sizeof(char);
}
else if ('*' == *pNext)
{//多行注释
scStart = pCur;
pCur = pNext + sizeof(char);
}
else
{//除号
pCur++;
}
}
break; case '*':
if (sqStart || dqStart || dcStart || (NULL == scStart))
{//忽略字符、字符串以及注释中的星号,忽略乘号
pCur++;
}
else
{
pNext = pCur + sizeof(char);
if ('/' != *pNext)
{//多行注释中间的星号,不处理
pCur++;
}
else
{
memset(scStart, ' ', pNext + sizeof(char) - scStart);
scStart = NULL;
}
}
break; case '\"':
if (sqStart || scStart || dcStart)
{//忽略字符以及注释中的双引号
pCur++;
}
else
{
if (dqStart)
{//双引号匹配成功
dqStart = NULL;
pCur++;
}
else
{
dqStart = pCur;
pCur++;
}
}
break; case '\'':
if (dqStart || scStart || dcStart)
{
pCur++;
}
else
{
if (sqStart)
{
len = pCur - sqStart;
if ((2 * sizeof(char) == len) && ('\\' == *(pCur - 1)))
{//忽略字符中的单引号
pCur++;
}
else
{
pCur++;
sqStart = NULL;
}
}
else
{
sqStart = pCur;
pCur++;
}
}
break; default:
pCur++;
break;
}
} //读到换行符后,进行相应操作
if(dcStart)
{
len = ((*(pCur - sizeof(char)) == '\r') ? (pCur - sizeof(char)) : pCur) - dcStart;
memset(dcStart, ' ', len);
dcStart = NULL;
}
if (sqStart)
{
sqStart = buff;
}
if (dqStart)
{
dqStart = buff;
}
if (scStart)
{
memset(scStart, ' ', pCur - scStart);
scStart = buff;
} fputs(buff, tempFile);
}
} int main(int argc, char* argv[])
{
FILE *pFile = NULL;
FILE *newFile = NULL; if (argc < 3)
{
fprintf(stderr, "usage: %s [OLD_FILE_NAME] [NEW_FILE_NAME]\n", argv[0]);
exit(1);
} if (NULL == (pFile = fopen(argv[1], "r+")))
{
fprintf(stderr, "open file failed\n");
exit(2);
} if (NULL == (newFile = fopen(argv[2], "w+")))
{
fprintf(stderr, "create newFile failed\n");
exit(3);
} DelComments(pFile, newFile); fclose(pFile);
fclose(newFile); return 0;
}