最近在做一個項目的移植工作,項目很大,光c文件大約有1800多。由於某些需要,想要對某些代碼文件引用的.h文件進行分析。
網上找了好久,暫無發現類似的工具。
正好,今天放假,就做了這麼個工具。
好了,廢話不多說了,先上圖。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Jonce { struct CType { public string FullPath; public string FileName; public List<string> IncludeList; } }
該類型用於描述每個代碼文件。
CFileHelper.cs文件內容:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Jonce { class CFileHelper { private List<string> fileList = new List<string>(); /// <summary> /// 獲取及分析所有C代碼文件 /// </summary> /// <param name="path">C項目路徑</param> /// <returns></returns> public List<CType> GetAllCFile(string path) { List<CType> retList = new List<CType>(); getAllByPath(path); //過濾出所有文件中的代碼文件 //分析引用,並存入List<CType>結構內 foreach (string item in fileList) { string extension = Path.GetExtension(item).ToLower(); if (extension == ".c" || extension == ".h" || extension == ".cpp") { CType cType = new CType(); cType.FullPath = item; cType.FileName = Path.GetFileName(item); //獲取C文件中include引用的頭文件 cType.IncludeList = SourceHelper.GetIncludeFile(SourceHelper.RemoveComments(item)); retList.Add(cType); } } return retList; } //獲取指定目錄下的所有文件 private void getAllByPath(string path) { if (path.EndsWith("\\")) { fileList.Add(path); } else { fileList.Add(path + "\\"); } string[] dirs = Directory.GetDirectories(path); fileList.AddRange(Directory.GetFiles(path)); foreach (string dir in dirs) { getAllByPath(dir.ToString()); } } } }
SourceHelper.cs文件內容:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Windows.Forms; using System.Text.RegularExpressions; namespace Jonce { class SourceHelper { /// <summary> /// 去掉代碼文件中的注釋 /// </summary> /// <param name="filePath">文件全路徑</param> /// <returns>文件前1M內容(去掉注釋)</returns> public static string RemoveComments(string filePath) { string retStr = ""; //1M緩沖區 char[] buffer = new char[1024 * 1024]; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs, Encoding.Default)) { try { //string fileStr = sr.ReadToEnd(); //讀取文件。只讀取<=1M內容 sr.Read(buffer, 0, buffer.Length); //字符數組轉換為字符串,進行正則匹配 string fileStr = new string(buffer); //正則表達式,匹配多行注釋和單行注釋 string regStr = @"/\*[\s\S]*?\*/|//.*"; //去掉多行注釋 retStr = Regex.Replace(fileStr, regStr, ""); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "ERR"); } } } return retStr; } /// <summary> /// 獲取C文件中include引用的頭文件 /// </summary> /// <param name="fileStr">文件全路徑</param> /// <returns>頭文件List集合</returns> public static List<string> GetIncludeFile(string fileStr) { List<string> headFileList = new List<string>(); //匹配include語句 string regStr1 = @"#\s*include\s(""|<).*"; //匹配頭文件 string regStr2 = @"\w+\.(h|H)\b"; Match mc1 = Regex.Match(fileStr, regStr1); while (mc1.Success) { Match mc2 = Regex.Match(mc1.ToString(), regStr2); if (mc2.Success) { headFileList.Add(mc2.ToString()); } mc1 = mc1.NextMatch(); } return headFileList; } } }
Form1.cs內容:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using DevComponents.Tree; namespace Jonce { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //選取目錄 FolderBrowserDialog fbd = new FolderBrowserDialog(); if (fbd.ShowDialog()==DialogResult.OK) { string path = fbd.SelectedPath; CFileHelper fileHelper = new CFileHelper(); //獲取及分析所有C代碼文件 List<CType> cTypeList = fileHelper.GetAllCFile(path); //treeGX.Node節點用style ElementStyle style = new ElementStyle(); //節點文字顏色設置 style.TextColor = Color.Blue; foreach (CType item in cTypeList) { if (Path.GetExtension(item.FullPath).ToLower() == ".c") { Node cNode = new Node(); cNode.Name = item.FileName; cNode.Text = item.FileName; cNode.Style = style; cNode.NodeDoubleClick += cNode_NodeDoubleClick; this.node1.Nodes.Add(cNode); loopDraw(cTypeList, item.FileName, ref cNode); } } //this.node1.ExpandAll(); this.node1.Text = path; //刷新treeGX this.treeGX1.Refresh(); } } void cNode_NodeDoubleClick(object sender, EventArgs e) { Node node = sender as Node; node.Expand(); //node.ExpandAll(); //throw new NotImplementedException(); } private void loopDraw(List<CType> cTypeList, string fileName,ref Node node) { foreach (CType item in cTypeList) { if (item.FileName==fileName) { foreach (string strItem in item.IncludeList) { Node incNode = new Node(); incNode.Name = strItem; incNode.Text = strItem; incNode.NodeDoubleClick += cNode_NodeDoubleClick; node.Nodes.Add(incNode); loopDraw(cTypeList, strItem, ref incNode); } } } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox1.SelectedItem==null) { return; } //DevComponents.Tree.eNodeLayout layout = (DevComponents.Tree.eNodeLayout)Enum.Parse(typeof(DevComponents.Tree.eNodeLayout), comboBox1.SelectedItem.ToString()); DevComponents.Tree.eMapFlow mapFlow = (DevComponents.Tree.eMapFlow)Enum.Parse(typeof(DevComponents.Tree.eMapFlow), comboBox1.SelectedItem.ToString()); if (treeGX1.MapLayoutFlow != mapFlow) { treeGX1.MapLayoutFlow = mapFlow; treeGX1.RecalcLayout(); treeGX1.Refresh(); } } private void button2_Click(object sender, EventArgs e) { this.node1.ExpandAll(); treeGX1.Refresh(); } private void button3_Click(object sender, EventArgs e) { this.node1.Nodes.Clear(); treeGX1.Refresh(); } } }
以上就是所有代碼,大家可以自己重新搭建一個。
當然,如果誰csdn下載積分多的,也可以下載整個項目:http://download.csdn.net/detail/geeking/8030119
只要兩個下載積分。本來想免費發的,可是我的積分一個也沒有了,很多資源都沒法下。shit,積分制度就是shit。
這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#include<stdio.h>
struct STU //定義一個結構體
{
int num;
}stu;
int main()
{
struct STU *p; //定義一個結構體指針
p=stu; //p指向stu這個結構體變量
stu.num=100; //給結構體成員num附個初值
printf("%d",p->num); //輸出stu中的num的值
return;
}
看到了吧,->的作法就是在引用結構體中的變量!!
形式如:p->結構體成員(如p->num)
他的作用相當於stu.num或(*p).num
不知道這樣解釋你明不明白、、、、、不懂了call我,O(∩_∩)O~
望采納。
這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#include<stdio.h>
struct STU //定義一個結構體
{
int num;
}stu;
int main()
{
struct STU *p; //定義一個結構體指針
p=stu; //p指向stu這個結構體變量
stu.num=100; //給結構體成員num附個初值
printf("%d",p->num); //輸出stu中的num的值
return;
}
看到了吧,->的作法就是在引用結構體中的變量!!
形式如:p->結構體成員(如p->num)
他的作用相當於stu.num或(*p).num
不知道這樣解釋你明不明白、、、、、不懂了call我,O(∩_∩)O~
望采納。