C#统计C、C++及C#程序代码行数的方法

时间:2022-04-21 08:21:13

本文实例讲述了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'结尾,因此遍历完毕后最后一行有没有有效字符,有则最后一行算作一行,没有则不算

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/// <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;
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <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函数

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
}

五、运行结果示例

C#统计C、C++及C#程序代码行数的方法

希望本文所述对大家的C#程序设计有所帮助。