用C++自制的源码统计工具

来源:互联网 发布:钱龙分析软件 编辑:程序博客网 时间:2024/05/16 12:00

之前决定看LevelDB是因为码量少,而且注释多,据说就2W来行。

于是写个程序统计,自己心里有个数。

下面是运行结果:


要统计的文件格式可以根据自己指定的regex表达式来筛选。

你可以修改CodeScanner.cpp中静态数据成员CodeScanner::file_type的初始化值来改变你希望统计的文件格式!

通过调用CodeScanner::TotalFileInfoIn("你需要统计的文件的绝对路径")即可得出目录下文件的总行数。


详见main方法!!!

所有操作都是通过调用CodeScanner的静态方法来实施!下面介绍一下这个类静态方法的功能。


//这个函数递归统计目录树的信息,将信息存入类的静态公有成员DirectoryTree。

TotalFileInfoIn("你需要统计的源码所在路径")


//这个函数负责统计每个文件的总行数,并且写入到一个fFileLine_map中。

CountDirectoryFileLineNum();


//这函数根据前两个函数的操作结果,以一个目录树的形式的打印出来!每个文件夹或者文件后面都跟着文件行数统计!

PrintDirectoryTree()


#include "CodeScanner.h"int main(void){CodeScanner::TotalFileInfoIn("E:\\开源代码\\leveldb\\leveldb-master");CodeScanner::CountDirectoryFileLineNum();CodeScanner::PrintDirectoryTree();return 0;}


下面是CodeScanner.h成员:

#pragma once#undef UNICODE#include<windows.h>#include<iostream>#include<string>#include<memory>#include<map>#include<vector>#include<regex>#include<fstream>using namespace std;class CodeScanner{public:CodeScanner();~CodeScanner();static map<string,vector<string>> TotalFileInfoIn(string path);static void PrintDirectoryTree(string pre_directory="",string sub_directory=RootPath,map<string,vector<string>> dir_map=DirectoryTree);static string RootPath;static map<string, vector<string>> DirectoryTree;static string file_type;static map<string, int> FileLine_map;static int CountDirectoryFileLineNum(string directory_name=RootPath);private:static int FileLine(string filename);inline static string PrintLevel(int blank) {string blankStr;while (blank > 0){blankStr.append(" ");--blank;}return blankStr;}};


下面是CodeScanner.cpp:

你可以通过改变正则表达式来决定需要统计的文件格式!

#include "CodeScanner.h"map<string, vector<string>> emptymap;map<string, vector<string>>CodeScanner::DirectoryTree=emptymap;string CodeScanner::RootPath = "";map<string, int> emptymap2 = { {"",0} };map<string, int> CodeScanner::FileLine_map = emptymap2;<span style="font-size:32px;">string CodeScanner::file_type=".+\\.(cpp|cxx|c|cc|h|md)$";</span>CodeScanner::CodeScanner(){}CodeScanner::~CodeScanner(){}map<string,vector<string>> CodeScanner::TotalFileInfoIn(string path){if (!RootPath.length())RootPath = path;if (path.length() == 0)return DirectoryTree;WIN32_FIND_DATA FileInfo;string FilePath;HANDLE handle;shared_ptr<char> CharPath;CharPath.reset(new char[path.length() + 5]);int index = 0;for (auto perchar : path)CharPath.get()[index++] = perchar;CharPath.get()[index++] = '\\';CharPath.get()[index++] = '*';CharPath.get()[index++] = '.';CharPath.get()[index++] = '*';CharPath.get()[index] = '\0';handle = FindFirstFile(CharPath.get(), &FileInfo);if (handle == INVALID_HANDLE_VALUE)return DirectoryTree;do{string subdirectory(FileInfo.cFileName);if (FileInfo.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY){if (subdirectory != "."&&subdirectory != ".."){DirectoryTree[path].push_back(subdirectory);TotalFileInfoIn(path + "\\" + subdirectory);}}else {DirectoryTree[path].push_back(subdirectory);} }while (FindNextFile(handle, &FileInfo));CharPath.get();return DirectoryTree;}void CodeScanner::PrintDirectoryTree(string pre_directory,string sub_directory,map<string, vector<string>> dir_map){string absoluteURL =(pre_directory.length()==0?pre_directory:pre_directory+"\\")+sub_directory;if (dir_map.find(absoluteURL)== dir_map.end())return;cout << PrintLevel(pre_directory.length())<< sub_directory<< ":" <<FileLine_map[absoluteURL]<<endl; for (auto dir_content : dir_map[absoluteURL]){if (dir_map.find(absoluteURL+"\\"+dir_content) == dir_map.end()) {cout << PrintLevel(absoluteURL.length()) <<dir_content<<":->"<<FileLine_map[absoluteURL+"\\"+dir_content]<<endl;}elsePrintDirectoryTree( absoluteURL,dir_content);}}int CodeScanner::FileLine(string filename){regex r(file_type,regex::icase);smatch legalfile;if (regex_search(filename, legalfile, r)) {int filelinenum = 0;string linecontent;ifstream filereader(filename,ifstream::in);if (filereader.good())while (getline(filereader, linecontent))++filelinenum;filereader.close();return filelinenum;}return 0;}int CodeScanner::CountDirectoryFileLineNum(string directory_name){if (DirectoryTree.find(directory_name)== DirectoryTree.end())  FileLine_map[directory_name]=FileLine(directory_name);else {string pre_directory = directory_name+"\\";for (auto sub_directory : DirectoryTree[directory_name])FileLine_map[directory_name] +=CountDirectoryFileLineNum(pre_directory + sub_directory);}return FileLine_map[directory_name];}


0 0
原创粉丝点击