本文實例講述了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#程序設計有所幫助。