这两天接手了一个项目,项目定义了一种自己语法,所以有了判断注释的需求。
这里自己简单实现了一个,代码非常精简。
提供的注释语法和C++是一模一样的, 允许 // 和 /* */两种注释
两个问题:
1、如何判断某一行是否为注释行。
2、如何判断是否“进入”了注释段,也就是在/* */中间。
先说第2点,思路:从上往下,一行一行的检查。
用一个flag标识是否”进入”了注释,具体在一行当中,遇到/* flag 置1,遇到 */ 置0;这样即使一行中有多个/* */也不会判断错误。
比如 /*int x*/ printf(); /* int y */ /*int z; 之后
就进入了注释段了,在遇到*/之前接下里的行都是注释行。但它本身并不是注释行。
这就说到第1点了,除了这个以下几种情况也都是注释行,如果一行是以//开头,仅有/*两个字符 ,仅有*/两个字符,以/*开头类似这种的/* xx */ /* x xxx */ //xxx,以/*开头类似 /* int x 这种的。
很自然的想到递归计算:
在一行中,前面部分闭合了就不用管了,把后面的子串继续递归。只要遇到上面说的几种情况中的一种就说明是注释行。递归结束还没遇到说明是普通行。
而且在递归中也可以更新flag是否进入了注释段。 两者可以在同一个函数中进行,非常方便。
判断一行本身是否为注释行以及更新/*、*/的函数如下。
bool Counter::judgeAndUpdateComment(string line, bool& flag)
{
// /* xxxxxx */ /* x xxx */ //xxxx
// /*xx */ int x /*
if(line[0] == '/' && line[1] == '/') return true;
if(line[0] == '*' && line[1] == '/' && line.length()==2) {flag = false; return true;}
if(line[0] == '/' && line[1] == '*' && line.length()==2) return flag = true;
if(line[0] == '/' && line[1] == '*' && line.find("*/")==string::npos) return flag = true;
string::size_type idx = line.find("/*");
if(idx != string::npos)
{
flag = true;
}
if(flag)
{
idx = line.find("*/");
if(idx != string::npos)
{
flag = false;
line[idx] = line[idx+1] = ' ';
string sub = line.substr(idx+2,line.length()-idx-2);
trim(sub);
if (judgeAndUpdateComment(sub,flag)) return true;
}
}
return false;
}
当然,要配合下面的函数里调用
void Counter::countOneFile(string filepath)
{
ifstream file;
file.open(filepath,ios::in);
if (!file.is_open())
{
cout << "can't open the file :" << filepath << endl;
exit(1);
}
char buffer[10000];
bool comment_flag = false;
while (!file.eof() )
{
file.getline(buffer,10000);
string line(buffer);
trim(line);
if (line.empty())
{
m_blank_line++;
}
else if(comment_flag) //如果已经进入了注释段
{
m_comment_line++;
judgeAndUpdateComment(line,comment_flag); //更新 */
}
else if (judgeAndUpdateComment(line,comment_flag)) // 本身是注释行
{
m_comment_line++;
}
else
{
m_real_line++;
}
}
cout << "finish: " << filepath << endl;
}
这里我没有考虑双引号的影响。双引号里的东西应该忽略的,但是我没有考虑,如果出现类似
string str = "abcd /* "; 的代码,程序得出的结果是灾难性的错误。有需要的同学自己加上。
完整代码 请点击:http://download.csdn.net/download/angon823/10115630