C++ 代码统计工具 & 判断一行代码是否为注释行

来源:互联网 发布:chromebook ubuntu 编辑:程序博客网 时间:2024/05/22 14:50

这两天接手了一个项目,项目定义了一种自己语法,所以有了判断注释的需求。

这里自己简单实现了一个,代码非常精简。


提供的注释语法和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