计算特殊符号的出现次数
本文关键字:特殊符号 计算 | 更新日期: 2023-09-27 18:28:20
我想计算一个程序的WMC。为此,我计算了2个"{"answers"}"符号之间的"void"、"return"、"main"、"set"answers"get"的数量,因为它们表示类的开始和结束。我使用以下代码:-
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);
}
}
}
}
问题是它识别单词,而不是"{"answers"}"符号。我已经尝试过在减少cflag变量后立即显示方法的数量,但没有使用
请帮忙!!!!
我相信这种拆分会更好:
string[] words = var1.Split(new char[] { ' ', ''r', ''n', ''t' },
StringSplitOptions.RemoveEmptyEntries);
您只能在''上拆分。如果你正在读取的文件是一个普通的源文件,它还包含其他类型的空白,你应该在上面进行拆分。回车、换行、制表。
完全有可能在{
后面直接跟一个非空格字符,所以你也应该检查一下。
我看不出你在哪里检查这些单词是否不在文字字符串中。
假设您要解析的文件是C#代码(我的假设是基于问题的标记,以及您要查找的关键字看起来像C#)。
与其尝试.Splitt()甚至正则表达式(我很惊讶还没有人建议这样做),因为它总是会有一些未正确处理的奇怪边缘情况,你能做的最好的事情就是将代码正确解析到语法树中。
幸运的是,微软已经完成了艰苦的工作。您可以向Roslyn编译器提供一个C#文件,然后返回语法树。这将为您提供对要查找的文件的最佳解析,并将为您带来最佳、无错误的结果。
附加读数:
- Roslyn MSDN页面
- 使用Roslyn解析C#代码文件
您遇到的问题是var1.Split(' ')
只在空格上拆分字符串。由于大多数大括号都以换行符结尾,而不是空格,因此收集的字符串不是单个"{"或"}"字符,而是该字符后面跟着换行符(''r'
或''n'
或两个字符"'r'n"
),后面跟着文件中下一行的开头。如果你愿意尝试的话,你正在收集的任何其他关键词都会发生同样的情况。
然而,这个问题并不仅仅局限于换行符。如果你的源代码在关键词旁边包含标点符号或运算符,那么你的代码目前也不会收集它。尝试一下:您的代码也不会在Main()
、(void)
、return(value)
、get{return val;}
或set{}
中收集任何关键字。
此外,您的代码不在乎在哪里找到关键字。例如,如果它在字符串文字中或注释内部找到Main
或return
,它将认为这是函数的开始或返回语句的开始,即使它们对C#程序的实际结构没有影响。
解决这些问题的最佳机会是首先放弃string.Split
,只遍历单个字符,自己收集关键字。即便如此,您仍然会在字符串和注释中收集不需要的关键字。如果你是一个完美主义者,并且你想避免收集这些,你可以在CSharp规范的§2中找到C#语言语法结构的生成(在64位系统上的"Program Files''Microsoft Visual Studio XXXX''VC#''Specifications''1033''CSharp language Specification.doc"或"Program Files(x86)…"中找到),但在大多数情况下,这有点过头了,你不认为吗?
也许您需要使用:
Regex r = new Regex(" +"); //specify delimiter (spaces)
string [] words = r.Split(var1); //(convert string to array of words)
if (word.Trim().Equals("Main")) { }