C# 使用c计算c程序中的函数数

C# 使用c计算c程序中的函数数,c#,C#,如何使用C程序计算C程序文件中的函数数?我创建了一个简单的C类来计算C文件中的LOC private bool IsInMultipleComment = false; private int getNumberOFFuncions(FileInfo fs) { StreamReader rdr; int count = 0; string tempStr; // initialize rdr = fs.OpenText(); tempSt

如何使用C程序计算C程序文件中的函数数?我创建了一个简单的C类来计算C文件中的LOC

private bool IsInMultipleComment = false; 

private int getNumberOFFuncions(FileInfo fs)
{

    StreamReader rdr;
    int count = 0;
    string tempStr;

    // initialize
    rdr = fs.OpenText();
    tempStr = rdr.ReadLine();

    while (true)
    {
        if (tempStr == null)
            break;
        if (IsFunction(tempStr))
            count++;
        tempStr = rdr.ReadLine();
    }
    return count;

}
支持方法:

private bool IsFunction(string line)
    {
        if (line.Contains("//"))
            return false;
        if (line.Contains("/*"))
            IsInMultipleComment = true;
        if (line.Contains("*/"))
            IsInMultipleComment = false;

        if (!IsInMultipleComment)
        {
            if (line.Contains("void") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
            {
                if (!line.Contains(";"))
                {
                    return true;
                }
            }
        }
        return false;
    }
private int getVariblesOfLine(string line)
    {
        line = line.Trim();  // trim the lines

        if (line.Contains("#"))     // remove preprocessive declarations
            return 0;
        if (line.Contains("//"))
            return 0;
        if (line.Contains("/*"))
            IsInMultipleComment = true;
        if (line.Contains("*/"))
            IsInMultipleComment = false;
        if (!IsInMultipleComment)
        {
            if (line.Contains("unsigned") || line.Contains("signed") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
            {
                if (!line.Contains("("))    // remove if this is function
                {
                    Console.WriteLine(line);
                    if (line.Contains(","))     // count at multiple declarations
                    {
                        int y = line.Count(f => f == ',');
                        return y + 1;
                    }
                    return 1;
                }
            }
        }
        return 0;
    }
这就是我计算变量的方法:

private int getNumberOfVariables(FileInfo fs)
    {
        StreamReader rdr;
        int count = 0;
        string tempStr;

        // initialize
        rdr = fs.OpenText();
        tempStr = rdr.ReadLine();

        while (true)
        {
            if (tempStr == null)
                break;
            count += getVariblesOfLine(tempStr);
            tempStr = rdr.ReadLine();
        }
        return count;
    }
支持方法:

private bool IsFunction(string line)
    {
        if (line.Contains("//"))
            return false;
        if (line.Contains("/*"))
            IsInMultipleComment = true;
        if (line.Contains("*/"))
            IsInMultipleComment = false;

        if (!IsInMultipleComment)
        {
            if (line.Contains("void") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
            {
                if (!line.Contains(";"))
                {
                    return true;
                }
            }
        }
        return false;
    }
private int getVariblesOfLine(string line)
    {
        line = line.Trim();  // trim the lines

        if (line.Contains("#"))     // remove preprocessive declarations
            return 0;
        if (line.Contains("//"))
            return 0;
        if (line.Contains("/*"))
            IsInMultipleComment = true;
        if (line.Contains("*/"))
            IsInMultipleComment = false;
        if (!IsInMultipleComment)
        {
            if (line.Contains("unsigned") || line.Contains("signed") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
            {
                if (!line.Contains("("))    // remove if this is function
                {
                    Console.WriteLine(line);
                    if (line.Contains(","))     // count at multiple declarations
                    {
                        int y = line.Count(f => f == ',');
                        return y + 1;
                    }
                    return 1;
                }
            }
        }
        return 0;
    }

我用这个类来计算变量、函数和loc

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace LineOfCounter
{
    class FileDialtion
    {

        private string FilePath;    // file path
        private string fileName;    //file name
        private long fileSize;      // file size
        private string extension;   // extension
        private bool readOnly;      // is file raad only
        private string creationTime;// file cration time    
        private string accessTime;  // last access time
        private long fileLOC;       // line of code insert in the file
        private int numOfFuncs;     // number of functions in thefile
        private int numOfVariables; // number of variables in the code
        private int numOfLV;        // number of local varibles
        private int numOfGV;        // number of globle variables
        private int numOfComments;  // number of Comments

        private int NumOfPPR = 0;// number of pre proccesssive derectories    
        private bool IsInMultipleComment = false;   // when starts multiple comment ignore Count

        #region getters

        public int getNumberOfPPR
        {
            get { return NumOfPPR; }
        }

        public int getNumOfVariables
        {
            get { return numOfVariables; }
        }

        public int getNumOfGlobleVariables
        {
            get { return numOfGV; }
        }

        public int getNumOfLocalVariables
        {
            get { return numOfLV; }
        }

        public int getNumberOfFunctions
        {
            get { return numOfFuncs; }
        }

        public int getNumberOfComment
        {
            get { return numOfComments; }
        }

        public string getFilePath
        {
            get
            {
                return FilePath;
            }

        }

        public string getFileName
        {
            get
            {
                return fileName;
            }

        }

        public string getFileSize
        {
            get
            {
                return fileSize.ToString();
            }

        }

        public string getFileExtension
        {
            get
            {
                return extension;
            }

        }

        public string getFileCreationtime
        {
            get
            {
                return creationTime;
            }

        }

        public string getFileAccessTime
        {
            get
            {
                return accessTime;
            }

        }

        public long getFileLOC
        {
            get
            {
                return fileLOC;
            }

        }

#endregion

        // class Constructor

        public FileDialtion(string filename) {

            try
            {
                FilePath = filename;

                FileInfo fi = new FileInfo(getFilePath);

                fileName = fi.Name;
                fileSize = fi.Length;
                extension = fi.Extension;
                readOnly = fi.IsReadOnly;
                creationTime = fi.CreationTime.ToString();
                accessTime = fi.LastAccessTime.ToString();
                fileLOC = getLOC(fi);   // read loc
                numOfComments = getNumberOfComments(fi); // get comments
                NumOfPPR = getNumberOfPPRs(fi);         // get pre processive directories
                numOfFuncs=getNumberOFFuncions(fi); // read functions
                numOfVariables = getNumberOfVariables(fi); // get number of variables
                numOfGV = getNumberOfGlobleVaariables(fi);   // getnumber of LocalVariables
                numOfLV = numOfVariables - numOfGV;
            }
            catch (Exception es)
            {
                Console.WriteLine(es.Message);
            }

        }

    #region main get Functuens

        private int getLOC(FileInfo fs) {
            StreamReader rdr;
            int count=0;

            rdr = fs.OpenText();
            while (rdr.ReadLine() != null)
            {
                count++;
            }
            return count;
        }

        private int getNumberOFFuncions(FileInfo fs) {

            StreamReader rdr;
            int count = 0;
            string tempStr;

            // initialize
            rdr = fs.OpenText();
            tempStr = rdr.ReadLine();

            while (true)
            {
                if (tempStr == null)
                    break;
                if(IsFunction(tempStr))
                    count++;
                tempStr = rdr.ReadLine();
            }
            return count;

        }

        private int getNumberOfVariables(FileInfo fs)
        {
            StreamReader rdr;
            int count = 0;
            string tempStr;

            // initialize
            rdr = fs.OpenText();
            tempStr = rdr.ReadLine();

            while (true)
            {
                if (tempStr == null)
                    break;
                count += getVariblesOfLine(tempStr);
                tempStr = rdr.ReadLine();
            }
            return count;
        }

        private int getNumberOfComments(FileInfo fs)
        {
            StreamReader rdr;
            int count = 0;
            string tempStr;

            // initialize
            rdr = fs.OpenText();
            tempStr = rdr.ReadLine();

            while (true)
            {
                if (tempStr == null)
                    break;
                if (IsComment(tempStr))
                    count++;
                tempStr = rdr.ReadLine();
            }
            return count;
        }

        private int getNumberOfPPRs(FileInfo fs)
        {
            StreamReader rdr;
            int count = 0;
            string tempStr;

            // initialize
            rdr = fs.OpenText();
            tempStr = rdr.ReadLine();

            while (true)
            {
                if (tempStr == null)
                    break;

                if (isPPR(tempStr))
                    count++;
                tempStr = rdr.ReadLine();
            }
            return count;
        }

        private int getNumberOfGlobleVaariables(FileInfo fs)
        {
            StreamReader rdr;
            int count = 0;
            string tempStr;

            // initialize
            rdr = fs.OpenText();
            tempStr = rdr.ReadLine();

            while (true)
            {
                if (tempStr == null)
                    break;

                count += getVariblesOfLine(tempStr); // count variables
                if (tempStr.Contains("main"))       // main function founds
                    break;
                tempStr = rdr.ReadLine();
            }
            return count;
        }

#endregion


#region Supportive Functions

        private bool IsFunction(string line)
        {
            if (line.Contains("//"))
                return false;
            if (line.Contains("/*"))
                IsInMultipleComment = true;
            if (line.Contains("*/"))
                IsInMultipleComment = false ;

            if (!IsInMultipleComment)
            {
                if (line.Contains("void") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
                {
                    if (!line.Contains(";"))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private bool isPPR(string line)
        {
            if (line.Contains("//"))
                return false;
            if (line.Contains("/*"))
                IsInMultipleComment = true;
            if (line.Contains("*/"))
                IsInMultipleComment = false;
            if (!IsInMultipleComment)
            {
                if (line.Contains("#"))
                {
                    return true;
                }
            }
            return false;
        }

        private bool IsComment(string sp)
        {
            if (sp.Contains("//"))
            {
                return true;
            }
            if (sp.Contains("/*"))
            {
                return true;
            }
            return false;
        }

        private int  getVariblesOfLine(string line)
        {
            line = line.Trim();  // trim the lines

            if (line.Contains("#"))     // remove preprocessive declarations
                return 0;
            if (line.Contains("//"))
                return 0;
            if (line.Contains("/*"))
                IsInMultipleComment = true;
            if (line.Contains("*/"))
                IsInMultipleComment = false;
            if (!IsInMultipleComment)
            {
                if (line.Contains("unsigned") || line.Contains("signed") || line.Contains("int") || line.Contains("short") || line.Contains("long") || line.Contains("float") || line.Contains("char") || line.Contains("double"))
                {
                    if (!line.Contains("("))    // remove if this is function
                    {
                        Console.WriteLine(line);
                        if (line.Contains(","))     // count at multiple declarations
                        {
                            int y = line.Count(f => f == ',');
                            return y + 1;
                        }
                        return 1;
                    }
                }
            }
            return 0;
        }

#endregion


    }
}

了解regex。函数声明是一种字符串模式。如果以普遍接受的.net方式使用declare函数,您不会捕获函数的所有可能扭曲,您可以获得其中的大部分。学习是一个很好的学习工具,可以帮助您了解正则表达式的模式

下面是一个识别函数的模式。看起来很疯狂,但事实并非如此。Expresso将为您解码。它还没有完全开发,因为它不会捕获私有函数,如果你没有在它前面加上private这个词,它也不会执行内部保护。可能还有更多的东西是它抓不到的

Regex regex = new Regex("\s*(private|public|internal|protected)\s*\w+\s+([a-zA-Z_0-9.]+)\s*\(.*\)",RegexOptions.Compiled)

if (regex.IsMatch(lineOfCode)
{
     //then it's a function
}
另一方面,不要一直打开并重新读取文件。打开一次,传球,就这样

我用javascript编写了一些代码来计算行数,在Csharp文件上,您可以提取一些正则表达式模式。请注意,在javascript中,/pattern/与.net模式相同,它是如何将正则表达式保存在.net中的对象字典中的

module.exports = ( function() {

    var classifiers = [] ;

    classifiers.push(
        {
            ctype: "using",
            regex: /^(\s*using\s*)([a-zA-Z_0-9.]+)/,
            extractMethod: function(lineInfo) {
                lineInfo.extractValue = lineInfo.line.split(this.regex)[2] ;
            }
        },
        {
            ctype: "namespace",
            regex: /^(\s*namespace\s*)([a-zA-Z_0-9.]+)/,
            extractMethod: function(lineInfo) {
                lineInfo.extractValue = lineInfo.line.split(this.regex)[2] ;
            }
        },
        {
            ctype: "comment",
            regex: /^\s*\/\/[/ A-Za-z,*]*/,
            extractMethod: function(lineInfo) {
                lineInfo.extractValue = null ;
            }
        },
        {
            ctype: "n/a",
            regex: /^\s*$|^\s*[;{}]+?\s*$/,
            extractMethod: function(lineInfo) {
                lineInfo.extractValue = null ;
            }
        }
    );

    function classifyLine(line, lineNo) {
        var lineInfo = {} ;
        lineInfo.line = line ;
        lineInfo.lineNo = lineNo;

        for (var index = 0; index < classifiers.length; index++) {
            var classifier = classifiers[index];

            if (classifier.regex.test(line)) {
                lineInfo.ctype = classifier.ctype;
                lineInfo.line = line ;
                classifier.extractMethod(lineInfo) ;
                break ;
            }
        }

        if (lineInfo.ctype == undefined){
            lineInfo.ctype = "code" ;           
        }

        return lineInfo ;
     }

     return {
        classifyLine : classifyLine    
    };

} )();

请显示您现在拥有的代码…我上传了一个我在下面创建的类文件。您应该使用相关代码编辑您的问题…我在下面添加了完整的类作为答案。我得到了结果。但不确定它是否正确。当然,您可以自己手动计数以验证其正确性,然后调试你的代码,看看为什么有些东西丢失了?例如,如果我的函数返回myclass的类,或者mystruct的结构,那么这段代码很容易被证明是错误的。当然,它可能与您的示例输入一起工作,但您可以非常轻松地提供它无法识别为函数的输入。不要重新发明轮子;使用现有的解析器/词法分析器。不使用正则表达式进行堆栈解析。这个密码坏了。这也是关于解释C代码,而不是C。使用正则表达式比我以前的一个更容易。非常感谢你的回复,并帮助我学习新的一个。