我想计算一个程序的WMC。为此,我数不清楚。 2“{”和“}”符号之间的“void”,“return”,“main”,“set”和“get”,因为它们表示类的开头n。我使用以下代码: -
namespace ConsoleApplication27
{
class Program
{
static void Main(string[] args)
{
int cflag=0,mflag=0;
string var1 = File.ReadAllText(@"c:\\Users\\kinnu\\My Documents\\program.txt");
string[] words = var1.Split(' ');
foreach (string word in words)
{
if (word == "{")
cflag++;
if (word == "}")
cflag--;
if (word == "Main")
mflag++;
if (word == "void")
mflag++;
if (word == "return")
mflag++;
if (word == "set")
mflag++;
if (word == "get")
mflag++;
if (cflag == 0)
Console.WriteLine("The number of methods are:" + mflag);
}
}
}
}
问题在于识别单词而不是“{”和“}”符号。我试过显示没有。在减少cflag变量但没有用的
之后的方法请帮助!!!!
答案 0 :(得分:2)
我相信这种分裂会更好:
string[] words = var1.Split(new char[] { ' ', '\r', '\n', '\t' },
StringSplitOptions.RemoveEmptyEntries);
答案 1 :(得分:1)
您遇到的问题是var1.Split(' ')
仅在空格上拆分字符串。由于大多数大括号以换行符结尾 - 而不是空格 - 因此收集的字符串不是单个“{”或“}”字符,而是字符后跟换行符('\r'
或{{ 1}}或两个字符'\n'
)后跟任何启动文件中下一行的内容。如果你想尝试,你收集的任何其他关键词都会发生同样的事情。
然而,问题不仅仅是与换行符分离。如果您的源代码在关键字旁边包含标点符号或运算符,那么您的代码当前也不会收集它。试一试:您的代码不会在"\r\n"
,Main()
,(void)
或return(value)
或get{return val;}
中收集任何关键字。
此外,您的代码并不关心找到关键字的位置。例如,如果它在字符串文字或注释内部找到set{}
或Main
,它会认为它是函数的开头或return语句的开头,即使它们有对C#程序的实际结构没有影响。
解决这些问题的最佳机会是首先放弃return
,然后迭代单个字符,自己收集关键字。即使这样,您仍然会在字符串和注释中收集不需要的关键字。如果你是一个完美主义者,并且你想避免收集它们,你可以在CSharp规范的§2中找到C#语言语法结构的产生(见“Program Files \ Microsoft Visual Studio XXXX \ VC#\ Specifications \ 1033”) \ CSharp语言规范.doc“,或64位系统上的”程序文件(x86)...“但是对于大多数情况来说这有点过分,你不觉得吗?
答案 2 :(得分:1)
你只能拆分''。如果您正在阅读的文件是平均源文件,它还包含您应该拆分的其他类型的空白。回车,换行,标签。
完全有可能让{
后跟一个非空格字符,所以你也应该检查一下。
我没看到你在哪里检查单词不在文字字符串中。
答案 3 :(得分:1)
假设您尝试解析的文件是C#代码(我将这个假设基于问题的标签,以及您要查找的关键字看起来像C#)。
而不是尝试.Split()甚至正则表达式(我很惊讶没有人推荐),这将总是有一些奇怪的边缘情况,没有妥善处理,你可以做的最好的事情就是正确将代码解析为语法树。
幸运的是,微软已经做了很多努力。您可以将C#文件提供给Roslyn编译器,然后返回语法树。这将为您提供几乎最好的解析文件,并为您提供最好,最无错误的结果。
补充阅读:
答案 4 :(得分:-2)
也许您需要使用:
Regex r = new Regex(" +"); //specify delimiter (spaces)
string [] words = r.Split(var1); //(convert string to array of words)
if (word.Trim().Equals("Main")) { }