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,换行)

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

1)遇到' '、'\r'、'\t'是无效字符,直接略过

2)遇到'\n',如果该行有有效字符,则认为该行有代码,否则认为没有

3)遇到字符'\"',则字符串开始,直到找到下一个字符'\"',中间忽略任何字符。注意字符如果找到的'\"'前有奇数个"\\",则跳过继续搜索。如果遇到'\n',则按代码行数自增1

4)遇到形如 /*...*/ 的注释,找到'/'和'*'相连的情况,则继续找'*'和'/'相连的情况。中间若有'\n',则看注释开始前该行是否有效,有效则算一行,无效则不算

5)遇到形如 //... 的注释,则看注释开始前该行是否有效,有效则算一行,无效则不算

6)遍历完整个文件后,由于最后一行可能不以'\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函数

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

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();
}

五、运行结果示例

110353_yOWc_1425762.png

转载于:https://my.oschina.net/Tsybius2014/blog/285839

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值