C#统计C、C++及C#程序代码行数的方法(所有代码行数,空行数,注释行数)

该文主要介绍了C#统计C、C++及C#程序代码行数的方法,较为详细的分析了C#统计文本文件的原理与相关实现技巧,具有一定参考借鉴价值。

具体如下:

本文中的两个函数

1)用于统计扩展名为 .h .c .cpp .cs 文件的代码行数

public static int LinesOfCode(string filename)

2)用于递归统计一个文件夹内所有扩展名为 .h .c .cpp .cs 文件的代码行数

public static int LinesOfFolder(string foldername)

一、什么样的情况算一行代码

需要注意如下几点:

1)如果一行为空,则不算作一行代码。在字符串中的空行除外,如:

Console.WriteLine(@"fasfew


fewafa");

2)Windows中的换行为\r\n,Linux中的换行为\n,因此判断隔行可以统一以\n计
(r:Carriage Return,回车;n:Linefeed,换行)

因此,判断算法采用以下步骤:

① 遇到' '、'\r'、'\t'是无效字符,直接略过
② 遇到'\n',如果该行有有效字符,则认为该行有代码,否则认为没有
③ 遇到字符'"',则字符串开始,直到找到下一个字符'"',中间忽略任何字符。注意字符如果找到的'"'前有奇数个"\",则跳过继续搜索。如果遇到'\n',则按代码行数自增1
④ 遇到形如 /.../ 的注释,找到'/'和''相连的情况,则继续找''和'/'相连的情况。中间若有'\n',则看注释开始前该行是否有效,有效则算一行,无效则不算
⑤ 遇到形如 //... 的注释,则看注释开始前该行是否有效,有效则算一行,无效则不算
⑥ 遍历完整个文件后,由于最后一行可能不以'\n'结尾,因此遍历完毕后最后一行有没有有效字符,有则最后一行算作一行,没有则不算

二、查看文件中的代码行数

/// <summary>
/// 检测一个C代码文件中的有效代码行数
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>代码行数</returns>
public static int LinesOfCode(string filename)
{
 System.IO.StreamReader sr = System.IO.File.OpenText(filename);
 string s = sr.ReadToEnd();
 sr.Close();
 bool isLine = false;  //一行中拥有有效字符时为true,该行可记入代码行数
 bool isCommitLf = false; //注释/*...*/中出现至少一个折行时为true
 int lines = 0;    //代码行数统计
 for (int i = 0; i < s.Length; i++)
 {
  //无效字符
  if (s[i] == ' ' || s[i] == '\r' || s[i] == '\t')
  {
   continue;
  }
  //搜索到换行,若该行有有效字符
  if (s[i] == '\n')
  {
   if (isLine)
   {
    lines++;
    isLine = false;
   }
   continue;
  }
  //字符串,占多少行按多少行算
  if (s[i] == '\"')
  {
   while (true)
   {
    i++;
    //如果文件遍历完毕则强行中止
    if (i >= s.Length)
    {
     break;
    }
    //再次遇到字符'"'且前方没有或有偶数个'//'时,中止循环并退出
    if (s[i] == '\"')
    {
     int sign = 0, counter = 0;
     while (true)
     {
      sign++;
      if (i - sign < 0)
      {
       break;
      }
      else if (s[i - sign] == '\\')
      {
       counter++;
      }
      else
      {
       break;
      }
     }
     if (counter % 2 == 0)
     {
      break;
     }
    }
    //字符串中的换行,直接算作一行代码
    if (s[i] == '\n')
    {
     lines++;
     isLine = true;
    }
   }
   isLine = true;
   continue;
  }
  //遇到形如 /*...*/ 的注释
  if (s[i] == '/' && i < s.Length - 1)
  {
   if (s[i + 1] == '*')
   {
    i++;
    while (true)
    {
     i++;
     //如果文件遍历完毕则强行中止
     if (i >= s.Length)
     {
      break;
     }
     if (s[i] == '\n')
     {
      if (isCommitLf == false)
      {
       if (isLine == true)
       {
        lines++;
        isLine = false;
       }
       isCommitLf = true;
      }
     }
     if (s[i] == '*' && i < s.Length - 1)
     {
      if (s[i + 1] == '/')
      {
       i++;
       break;
      }
     }
    }
    isCommitLf = false;
    continue;
   }
  }
  //遇到形如 // 的注释
  if (s[i] == '/' && i < s.Length - 1 && s[i + 1] == '/')
  {
   if (isLine == true)
   {
    lines++;
    isLine = false;
   }
   while (true)
   {
    i++;
    if (i >= s.Length || s[i] == '\n')
    {
     break;
    }
   }
   continue;
  }
  //该行有了有效字符,算作一行
  isLine = true;
 }
 //最后一行可能没有字符'\n'结尾
 if (isLine)
 {
  lines++;
 }
 return lines;
}

三、查看文件夹中所有代码文件的代码行数

/// <summary>
/// 检测一个文件夹中所有C代码的行数
/// </summary>
/// <param name="foldername">文件夹名称</param>
/// <returns>代码行数</returns>
public static int LinesOfFolder(string foldername)
{
 //行数统计
 int lines = 0;
 //文件夹信息
 System.IO.DirectoryInfo dif = new System.IO.DirectoryInfo(foldername);
 //遍历文件夹中的各子文件夹
 foreach (System.IO.DirectoryInfo di in dif.GetDirectories())
 {
  lines += LinesOfFolder(di.FullName);
 }
 //统计本文件夹中C语言文件代码
 foreach (System.IO.FileInfo f in dif.GetFiles())
 {
  if (f.Extension == ".cs" || f.Extension == ".cpp" ||
   f.Extension == ".c" || f.Extension == ".h")
  {
   lines += LinesOfCode(f.FullName);
  }
 }
 return lines;
}

四、Main函数

<p>输入命令 checkfile:文件名 或 checkfolder:文件夹路径 查询</p>

static void Main(string[] args)
{
 Console.WriteLine("请输入要统计的文件或文件夹");
 Console.WriteLine("输入示例:checkfile:xxx / checkfolder:xxx");
 try
 {
  string order = Console.ReadLine();
  string[] temp = order.Split(':');
  if (temp.Length < 2)
  {
   Console.WriteLine("语法错误,程序结束");
  }
  switch (temp[0])
  {
   case "checkfile":
    {
     int count = LinesOfCode(order.Substring(10).Trim());
     Console.WriteLine("共有代码 " + count + " 行");
    } break;
   case "checkfolder":
    {
     int count = LinesOfFolder(order.Substring(12).Trim());
     Console.WriteLine("共有代码 " + count + " 行");
    } break;
   default: Console.WriteLine("未知命令"); break;
  }
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.Message);
 }
 Console.ReadLine();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容

  • .bat脚本基本命令语法 目录 批处理的常见命令(未列举的命令还比较多,请查阅帮助信息) 1、REM 和 :: 2...
    庆庆庆庆庆阅读 8,018评论 1 19
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,689评论 0 10
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,094评论 0 13
  • 第一次投笔试就挂了。以此留念吧 ?xml version="1.0" encoding="UTF-8"? 本文框架...
    eb4dd83e12f5阅读 1,435评论 0 2
  • 此类不与百花同,碧波潋滟露芙蓉。 出泥不染清高贵,迎飓难折玉骨铮。 蜻蜓乐于常青睐,鱼蛙歇息蓬下停。 仙鹤献花南海...
    花开在眼前阅读 376评论 14 3