程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c# 簡易繪制C語言頭文件包含關系圖,

c# 簡易繪制C語言頭文件包含關系圖,

編輯:C#入門知識

c# 簡易繪制C語言頭文件包含關系圖,


最近在做一個項目的移植工作,項目很大,光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。


C語言裡面,這個符號(->)是什,怎使用?

這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#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~
望采納。
 

C語言裡面,這個符號(->)是什,怎使用?

這是結構體指針中的一個符號,給你寫個程序解釋一下吧,例如:
#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~
望采納。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved