C#統(tǒng)計(jì)C、C++及C#程序代碼行數(shù)的方法
本文實(shí)例講述了C#統(tǒng)計(jì)C、C++及C#程序代碼行數(shù)的方法。分享給大家供大家參考。具體如下:
本文中的兩個函數(shù)
1)用于統(tǒng)計(jì)擴(kuò)展名為 .h .c .cpp .cs 文件的代碼行數(shù)
public static int LinesOfCode(string filename)
2)用于遞歸統(tǒng)計(jì)一個文件夾內(nèi)所有擴(kuò)展名為 .h .c .cpp .cs 文件的代碼行數(shù)
public static int LinesOfFolder(string foldername)
一、什么樣的情況算一行代碼
需要注意如下幾點(diǎn):
1)如果一行為空,則不算作一行代碼。在字符串中的空行除外,如:
Console.WriteLine(@"fasfew
fewafa");
2)Windows中的換行為\r\n,Linux中的換行為\n,因此判斷隔行可以統(tǒng)一以\n計(jì)
(r:Carriage Return,回車;n:Linefeed,換行)
因此,判斷算法采用以下步驟:
① 遇到' '、'\r'、'\t'是無效字符,直接略過
② 遇到'\n',如果該行有有效字符,則認(rèn)為該行有代碼,否則認(rèn)為沒有
③ 遇到字符'\"',則字符串開始,直到找到下一個字符'\"',中間忽略任何字符。注意字符如果找到的'\"'前有奇數(shù)個"\\",則跳過繼續(xù)搜索。如果遇到'\n',則按代碼行數(shù)自增1
④ 遇到形如 /*...*/ 的注釋,找到'/'和'*'相連的情況,則繼續(xù)找'*'和'/'相連的情況。中間若有'\n',則看注釋開始前該行是否有效,有效則算一行,無效則不算
⑤ 遇到形如 //... 的注釋,則看注釋開始前該行是否有效,有效則算一行,無效則不算
⑥ 遍歷完整個文件后,由于最后一行可能不以'\n'結(jié)尾,因此遍歷完畢后最后一行有沒有有效字符,有則最后一行算作一行,沒有則不算
二、查看文件中的代碼行數(shù)
/// <summary> /// 檢測一個C代碼文件中的有效代碼行數(shù) /// </summary> /// <param name="filename">文件名</param> /// <returns>代碼行數(shù)</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,該行可記入代碼行數(shù) bool isCommitLf = false; //注釋/*...*/中出現(xiàn)至少一個折行時為true int lines = 0; //代碼行數(shù)統(tǒng)計(jì) 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++; //如果文件遍歷完畢則強(qiáng)行中止 if (i >= s.Length) { break; } //再次遇到字符'"'且前方?jīng)]有或有偶數(shù)個'//'時,中止循環(huán)并退出 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++; //如果文件遍歷完畢則強(qiáng)行中止 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'結(jié)尾 if (isLine) { lines++; } return lines; }
三、查看文件夾中所以代碼文件的代碼行數(shù)
/// <summary> /// 檢測一個文件夾中所有C代碼的行數(shù) /// </summary> /// <param name="foldername">文件夾名稱</param> /// <returns>代碼行數(shù)</returns> public static int LinesOfFolder(string foldername) { //行數(shù)統(tǒng)計(jì) int lines = 0; //文件夾信息 System.IO.DirectoryInfo dif = new System.IO.DirectoryInfo(foldername); //遍歷文件夾中的各子文件夾 foreach (System.IO.DirectoryInfo di in dif.GetDirectories()) { lines += LinesOfFolder(di.FullName); } //統(tǒng)計(jì)本文件夾中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函數(shù)
輸入命令 checkfile:文件名 或 checkfolder:文件夾路徑 查詢
static void Main(string[] args) { Console.WriteLine("請輸入要統(tǒng)計(jì)的文件或文件夾"); Console.WriteLine("輸入示例:checkfile:xxx / checkfolder:xxx"); try { string order = Console.ReadLine(); string[] temp = order.Split(':'); if (temp.Length < 2) { Console.WriteLine("語法錯誤,程序結(jié)束"); } 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(); }
五、運(yùn)行結(jié)果示例
希望本文所述對大家的C#程序設(shè)計(jì)有所幫助。
- C# 調(diào)用C++寫的dll的實(shí)現(xiàn)方法
- C++調(diào)用C#的DLL實(shí)現(xiàn)方法
- C++與C#互調(diào)dll的實(shí)現(xiàn)步驟
- C#調(diào)用C++版本dll時的類型轉(zhuǎn)換需要注意的問題小結(jié)
- C++聯(lián)合體轉(zhuǎn)換成C#結(jié)構(gòu)的實(shí)現(xiàn)方法
- c++與c#的時間轉(zhuǎn)換示例分享
- c++函數(shù)轉(zhuǎn)c#函數(shù)示例程序分享
- C++調(diào)用C#的DLL程序?qū)崿F(xiàn)方法
- C#如何調(diào)用原生C++ COM對象詳解
相關(guān)文章
C# httpwebrequest訪問HTTPS錯誤處理方法
下面小編就為大家?guī)硪黄狢# httpwebrequest訪問HTTPS錯誤處理方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01