设为首页 加入收藏

TOP

C++统计代码注释行数 & 有效代码行数 & 代码注释公共行 & 函数个数(一)
2015-07-20 17:53:51 来源: 作者: 【 】 浏览:7
Tags:统计 代码 注释 有效 公共 函数个数
问题来源,在14年的暑假的一次小项目当中遇到了一个这样的问题,要求统计C++代码的注释行数,有效代码行数,代码注释公共行数,以及函数个数。
?
下面稍微解释一下问题,
?
1)注释行数:指有注释的行,包括有代码和注释的公共行(如:3,4,15,22...)
?
2)有效代码行:指有代码的行,包括有代码和注释的公共行(如:1,4,11,15,25....)
?
3)代码注释公共行:指又有代码又有注释的行(如:4,15...)
?
4)函数个数:这个不用说明了吧。
?
以下为注释情况展示代码:
?
复制代码
?1 #include
?2?
?3 //follow is a common line
?4 void swap(char *p/* = NULL */)
?5 {
?6 ? ? printf("this is a function /*is not comments*/");
?7 }
?8?
?9 int main(void)
10 {
11 ? ? int a = 10;
12 ? ? int b;
13 ? ? char *p = NULL;
14?
15 ? ? swap(p); ?//common line
16 ? ? if (10 == a)
17 ? ? {
18 ? ? ? ? printf("is not function;//is not comments");
19 ? ? }
20 ? ? //pure comments/*no use*/
21?
22 ? ? /*a = 5;
23 ? ? printf("not use\n");*/
24?
25 ? ? b = 3;/*i'm a comment*/ a = 5; /*comments line
26 ? ? pure //comments line;"*/......"look there*/
27 ? ? printf("test \" escape char");
28 ? ? //and the follow,maybe affect the count of function
29 ? ? if (*p == '{')
30 ? ? {
31 ? ? ? ? printf("the '{' is a question\n");
32 ? ? }
33 ? ? //
34?
35 ? ? return 0;
36 }
复制代码
上面的这个代码片段,已经基本上展示了各种注释可能出现的情况,接着我们来分析一下注释出现的位置:
?
一、“//”双斜杠注释
?
1)可能出现在行头部,如:第3行;
?
2)可能出现在行末尾,如:第15行;
?
注意:第18行,第26行。第18行中,//位于双引号中,注释失效;第26行中,//位于/**/注释中,//失效。
?
二、“/**/”斜杠星注释
?
1)可能出现在函数参数里,如:第4行;
?
2)可能注释一个段落,如:22,23行;
?
3)也可能出现在代码中部,如25,26行那样的复杂注释;
?
注意:第20行,第26行。第20行,/**/位于//注释中,失效。第26行,有一个*/位于“”中,*/失效。
?
好了,位置分析完毕,下面分析一下如何设计算法:
?
三、具体算法设计思路
?
1)解决文件读取
?
这里我们用c++文件读取,每次读取一行,将读取结果放到string变量里面,这样string变量尾部自动为'\0'。我们用于判断行尾部。
?
2)双引号问题
?
由于双引号里面的内容都是无效的,所以我们可以直接来个过滤双引号里面的内容。(具体实现见代码)
?
3)单引号问题
?
上面的展示代码里面也看到了,单引号里面的内容(如:if (ch == '{'))可能会影响函数个数的统计,所以我们需要过滤单引号。
?
4)空行
?
这个最简单,如果string为空就是空行。包括(\t\n\r' '等等,无效字符,都算空行)。
?
5)“//”注释
?
这个较为简单,遇到//就可以进行统计,同时该行也不需要继续遍历了,直接break;然后读取下一行。
?
6)“/**/”注释
?
较麻烦,我们这里用到了代码标记,注释标记,同时还设置了当遍历到行最尾部的时候,才进行行数统计,这样避免了一行被统计多次。(具体实现见代码)
?
7)函数个数
?
首先说一下统计思路,我们统计函数的时候,只是以大括号({})为统计标记。用栈来表示,遇到左括号,入栈;遇到右括号,弹出一个左括号。知道弹到栈空,函数个数+1,
?
这样的话,就实现了只保留最外层那对{},里层的括号全部抵销。我们又想了一下,简化了一下,不用栈,直接用一个变量来表示括号个数,遇到左括号,++top;遇到右括号--top,直到top==0,也就相当于栈空,函数个数+1。
?
其实如下代码的函数个数统计还有问题:
?
示例:对于类、结构体、枚举体、全局数组,会被统计为一个函数。也就是说,那些在函数体外面的,但是又带有大括号({})的代码,都会被识别为函数。
?
以下为实现代码:
?
复制代码
? 1 #include
? 2 #include
? 3 #include
? 4 using namespace std;
? 5?
? 6 int main(void)
? 7 {
? 8 ? ? string line="";
? 9 ? ? ifstream ifs;
?10 ? ? ifs.open("Test.cpp");
?11 ? ? if (!ifs)
?12 ? ? {
?13 ? ? ? ? cout<<"文件打开失败"<
?14 ? ? ? ? exit(0);
?15 ? ? }
?16 ? ? //////////////////////////////////////////////
?17 ? ? //标记:双引号 斜杠星 ? 函数 ? ? ?代码 ? ? ? ?注释
?18 ? ? int bSyh = 0, bXgx = 0, bHs = -1, bCode = 0, bZs = 0;
?19 ? ? // ? "" ? ? ? ?'' ? ? ? ?// ? ? /* ? ? ? ?{}
?20 ? ? /////////////////////////////////////////////
?21 ? ? //个数:空行 ?注释 ? ?代码 ? ? ?公共 ? ? 函数
?22 ? ? int i,nKh = 0, nZs = 0, nDm = 0, nGg = 0, nHs = 0;
?23 ? ? //
?24 ? ? while (!ifs.eof())
?25 ? ? {
?26 ? ? ? ? i = 0;
?27 ? ? ? ? getline(ifs,line); ? ?//读取一行文件
?28 ? ? ? ? bCode = 0; ? ? ? ? ? ?//该行没有代码
?29 ? ? ? ? bZs = 0; ? ? ? ? ? ? ?//该行没有注释
?30 ? ? ? ? if (bXgx) ? ? ? ? ? ? //bXgx 斜杠星注释标记
?31 ? ? ? ? ? ? bZs = 1; ? ? ? ? ?//该行有注释
?32 ? ? ? ? //过滤无效符号?
?33 ? ? ? ? while (line[i] == ' ' || line[i] == '\t
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇UVA 10869 - Brownie Points II(.. 下一篇HDU4509-湫湫系列故事――减肥记I..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: