统计C/C++代码行数

近日在写一个统计项目中 C/C++文件(后缀名:C/CPP/CC/H/HPP文件)代码行数的小程序。给定包含C/C++代码的目录,统计目录里所有C/C++文件的总代码行数、有效代码行数、注释行数、空白行数。

其中:总代码行数 =(有效代码行数+注释行数+空白行数)

每找到一个目标代码文件,就创建任务投进线程池。线程池的设计基于任务,基于任务相比基于线程的优势,请参考Scott Meyers撰写的Moderm Effective C++一书。

先给出程序运行的效果,见下图:

统计C/C++代码行数

近5万的代码文件,1183万总代码行数,不到5分钟统计完成,速度还是很快的。有人问了,用5分钟才统计完,怎么也不能说快吧。咱不耍嘴皮子,用结果说话。作为对比的上面那款源码统计专家工具,在对同一个目录里的文件进行分析统计时,半个小时过去还没给出结果。这工具单文件分析都不准,面对5万个文件,结果只怕会错的离谱,运行又慢,我想也没等下去的必要了,果断给×掉了。

需要程序的,可以在文末评论留下邮箱O(∩_∩)O

对代码文件的分析中,空白行好处理,关键在于识别有效代码和注释代码。大的识别原则有:

1.注释符合文法,不能让编译期报错。这是最重要的原则。

2.注释中的空行是空行,原始字符串中的空行不是空行

3.原始字符串里的注释(行注释/块注释)是有效代码,不能当作注释统计

4.注释中的原始字符串是注释,不能当作有效代码统计

为了验证程序逻辑的严密性和准确性,设计了如下的复杂的代码片段:

 1 // idxRawStringStart = curLine.find(R"(R"()");
 2 string comment_test = R"({
 3       // comment /* with nested comment */
 4       // comment
 5       "a": "text",
 6       /* multi
 7         // line-comment-inside-multiline-comment
 8       */
 9       
10     })";
11 
12 idxRawStringStart = curLine.find(R"(R"()");
13 idxRawStringStart = curLine.find(R"(R"(
14 )");
15 /**************************************************************************
16 *    功能描述:
17 **************************************************************************/
18 /*
19 
20          * Since some memmove()'s erroneously fail to handle
21          * overlapping regions, we'll do the shift by hand.
22          */
23 int a = /*b*/ 0;
24 int b = 0 // comment
25 /*a = b*/
26 // int a = b;
27  }
28  /////////////////////////////////////////////////////////////////////////
29 }

 

这29行代码中,从程序员的角度看,绿色部分是注释共11行,红色部分是代码共16行,line 9是空行但因为包含在原始字符串中,所以是有效代码行。

真正的空行只有 line 11和19,共2行。

对于这么个复杂代码段,市面上某号称源码统计专家的工具给出的结果如下:

统计C/C++代码行数

 

可以看到,在面对注释风格多变且复杂的代码文件时,专家工具变“砖”家,结果毫不可信。

而本程序输出结果,完全正确。

统计C/C++代码行数

 

 上述复杂代码段中,值得关注的是原始字符串的处理,其语法为R"()",小括号内放原始字符串的内容

 1 std::string comment_test = R"({
 2       // comment /* with nested comment */
 3       "a": 1,
 4       // comment
 5       // continued
 6       "b": "text",
 7       /* multi
 8          line
 9          comment
10         // line-comment-inside-multiline-comment
11       */
12       // and single-line comment
13       // and single-line comment /* multiline inside single line */
14       "c": [1, 2, 3]
15       // and single-line comment at end of object
16     })";

conmment_tes存放的内容是

统计C/C++代码行数

就是说里面的// 和/* */注释符号不能被认定为注释符号,哪怕它们在其中混用,注释嵌套着注释,不管是多复杂的组合,也是原始字符串的一部分,是有效代码。程序的目的就是利用原始字符串的语法构造规则,找出原始字符串的起始和结束位置。

在识别过程中,本程序做的工作其实是编译期语法/词法分析的一部分功能,这也让我更加了解原始字符串和嵌套注释的语法规则。特别地,发现了vs注释一个有意思的地方。vs注释的快捷键会优先选择/**/风格注释,在/**/不能胜任的地方,会使用//代替。

以前看过一篇文章,建议注释只用//,而不要用/* */,更不要用嵌套的/* */,因为后两种注释加大了文本分析程序解析的难度。 如果注释用//开头,很容易就识别该行代码就是注释了。我在做这个代码行统计小程序时,对这条建议有了更深的体会。用//代替/**/这个建议,应该作为代码规范执行下去。

 写程序难免踩坑,在这里记下来,避免后面踩到同样的坑。

1. 在控制台程序输入文件夹路径时,路径如果包含空格,cmd会把空格前后内容当作不同的参数,程序处理参数会错误(路径无效)。把路径用双引号包含起来后就正常了。

统计C/C++代码行数

2.程序在控制台运行出现中文乱码,工程设置是unicode,程序打印的文件路径含中文,而控制台默认代码页是936,GBK,开发环境和输出环境编码不一致,所以会乱码。

乱码截图一张,图中的问号其实是中文。

统计C/C++代码行数

为适应控制台的编码,使用setlocale(LC_CTYPE, "")就好了;

3.标准库里的ofstream的<<重载符,对宽字符的处理不好,比如写入std::wstring内容会出错,而使用std::string则不会有问题。但代码路径有中文的情况下,无法输出。解决办法就是把ofstream换成wofstream。同时调用file.imbue(locale("", locale::all ^ locale::numeric));设置中文输出环境。

4.标准库的向量容器push_back(插入元素)非线程安全,在多线程环境下往此容器里写东西时需加锁。当然标准库里的大多数容器操作都是非线程安全的,使用时需谨慎。

原文链接: https://www.cnblogs.com/japelly/p/10001495.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    统计C/C++代码行数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/285465

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
adminadmin
0 0
DB2 数据库的安装配置及监控
上一篇 2023年2月15日 上午8:38
C++常用数据结构的实现
下一篇 2023年2月15日 上午8:39

相关推荐

  • 实用主义 2023年2月7日
  • C++_对象成员 2023年2月15日
  • RedHat Linux上安装PostgreSQL 2023年2月8日
  • c++中使用指针调用函数和使用指针调用类对象的()重载函数 2023年2月15日
  • C++ 返回const对象 2023年3月2日
  • cvMatND 多维数组 设置和读取像素值 2023年2月9日
  • 12.6K

    我是职场上失宠的妃子

  • C++性能真的不如C吗?

    7.1K
  • 大话数据结构 高清PDF

    6.7K
  • string底层实现之SSO

    6.3K
  • 千百撸

    4.4K
  • GDB调试-从入门实践到原理

    3.7K
  • 什么是COM

    3.6K
  • std::string底层实现之COW(Copy-On-Write)

    3.6K
  • 智能指针-使用、避坑和实现

    3.5K
  • 彻底搞通TCP send和recv原理

    3.4K

深圳SEO优化公司宿迁SEO按天收费推荐贵阳关键词排名包年推广多少钱三亚网站优化按天计费推荐榆林品牌网站设计公司毕节外贸网站建设晋城关键词按天收费报价随州网站优化软件推荐布吉百度爱采购推荐宿迁百度标王价格营口关键词按天计费哪家好普洱企业网站建设报价昭通seo网站推广价格晋中推广网站菏泽seo优化多少钱丽水SEO按效果付费推荐保山网站优化推广多少钱荆门百姓网标王多少钱玉树模板制作公司嘉兴模板网站建设玉溪百度竞价包年推广公司黔南百度竞价推荐阿里网站设计益阳网站推广系统公司玉树百搜标王价格德宏seo公司揭阳外贸网站建设价格桂林seo网站优化公司北京企业网站建设报价东莞seo网站推广价格北海网站制作设计哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化