您的位置:首页 > 编程语言 > C语言/C++

C++ 一个统计文件夹下所有代码文件行数的小工具

2016-11-09 11:33 966 查看
// CodeLines.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Commdlg.h>
#include <Shlobj.h>
#include <map>
#include <vector>
#include <iostream>
#include <io.h>
#include <string>
#include <set>
#include <fstream>
#pragma comment(lib,"Shell32.lib")

void InitValidTypes(std::set<std::string> &validTypes)
{
validTypes.insert(".h");
validTypes.insert(".cpp");
validTypes.insert(".c");
validTypes.insert(".hpp");
validTypes.insert(".py");
validTypes.insert(".txt");
validTypes.insert(".cs");
validTypes.insert(".css");
validTypes.insert(".js");
validTypes.insert(".lua");
validTypes.insert(".html");
validTypes.insert(".htm");
validTypes.insert(".java");
validTypes.insert(".bat");
validTypes.insert("makefile");
}

int32_t WToChar(LPWSTR szWstr, char szCstr[], const int32_t chrLen)
{
int iLength = WideCharToMultiByte(CP_ACP, 0, szWstr, -1, NULL, 0, NULL, NULL);
return WideCharToMultiByte(CP_ACP, 0, szWstr, -1, szCstr, iLength, NULL, NULL);
}

void OpenDirectoryDialog(HWND hWnd, char directoryPath[], const int32_t directoryPathLen)
{
TCHAR szBuffer[MAX_PATH] = { 0 };
BROWSEINFO bi = { 0 };
bi.hwndOwner = hWnd;//拥有着窗口句柄,为NULL表示对话框是非模态的,实际应用中一般都要有这个句柄
bi.pszDisplayName = szBuffer;//接收文件夹的缓冲区
bi.lpszTitle = TEXT("选择一个文件夹");//标题
bi.ulFlags = BIF_NEWDIALOGSTYLE;
BOOL ret = FALSE;
do{
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
ret = SHGetPathFromIDList(idl, szBuffer);
if (!ret)
{
MessageBox(NULL, TEXT("请选择一个文件夹"), NULL, MB_ICONERROR);
}
else
{
//MessageBox(NULL, szBuffer, TEXT("你选择的文件夹"), 0);
WToChar(szBuffer, directoryPath, directoryPathLen);
}
} while (!ret);
}

void GetFilesFromDirectory(std::vector<std::string> &files, const char *directoryPath)
{
struct _finddata_t fileinfo;
long hFile = 0;
char tmpPath[MAX_PATH] = { 0 };
sprintf_s(tmpPath, "%s\\*", directoryPath);
if ((hFile = _findfirst(tmpPath, &fileinfo)) == -1){ return; }
do
{
if ((fileinfo.attrib &  _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
sprintf_s(tmpPath, "%s\\%s", directoryPath, fileinfo.name);
GetFilesFromDirectory(files, tmpPath);
}
}
else
{
sprintf_s(tmpPath, "%s\\%s", directoryPath, fileinfo.name);
files.push_back(tmpPath);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}

void StringToLower(std::string &str)
{
for (uint32_t i = 0; i < str.length(); ++i)
{
if (str[i] >= 'A' && str[i] <= 'Z')
{
str[i] = str[i] + 'a' - 'A';
}
}
}

std::string GetFileExtention(const std::string &fileName)
{
std::string localFileName = fileName;
StringToLower(localFileName);
int pos = localFileName.find_last_of('.');
if (pos >= 0)
{
return localFileName.substr(pos);
}
return localFileName;
}

void DumpFiles(const std::vector<std::string> &files)
{
for (uint32_t i = 0; i < files.size() && i < 100; ++i)
{
std::cout << files[i] << std::endl;
std::cout << GetFileExtention(files[i]) << std::endl;
}
std::cout << files.size() << std::endl;
}

bool IfFileTypeValid(const std::string &fileExtention)
{
static std::set<std::string> validTypes;
if (validTypes.empty()){
InitValidTypes(validTypes);
}
return validTypes.find(fileExtention) != validTypes.end();
}

uint32_t CalculateCharShowTimesInBuf(char buf[], const uint32_t len, char aim)
{
uint32_t i = 0,counter = 0;
while (i < len && buf[i] != '\0')
{
if (buf[i] == aim){ ++counter; }
++i;
}
return counter;
}

uint32_t GetFileLines(const std::string &fileName)
{
const uint32_t maxBufLen = 10240;
static char buf[maxBufLen + 1];
std::ifstream inFile(fileName, std::ios::in);
if (!inFile){ return 0; }
uint32_t counter = 0;
while (!inFile.eof())
{
memset(buf, 0, maxBufLen);
inFile.read(buf, maxBufLen);
//std::cout << buf;
counter += CalculateCharShowTimesInBuf(buf, maxBufLen, '\n');
}
return counter;
}

void StatisticCodeLines(std::map<std::string, uint32_t> &codeLines, const std::string &directoryPath)
{
static std::vector<std::string> files;
files.clear();
GetFilesFromDirectory(files, directoryPath.c_str());
// DumpFiles(files);
for (const std::string &fileName : files)
{
std::string fileExtention = GetFileExtention(fileName);
if (!IfFileTypeValid(fileExtention)){ continue; }
codeLines[fileExtention] += GetFileLines(fileName);
}
}

void PrintCodeLines(const std::map<std::string, uint32_t> &codeLines)
{
for (const std::pair<std::string, uint32_t> &p : codeLines)
{
printf("%-6s:%-8u\n", p.first.c_str(), p.second);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
char directoryPath[MAX_PATH] = { 0 };
OpenDirectoryDialog(NULL, directoryPath, MAX_PATH);
std::cout << directoryPath << std::endl;
static std::map<std::string, uint32_t> codeLines;
codeLines.clear();
StatisticCodeLines(codeLines, directoryPath);
PrintCodeLines(codeLines);
getchar();
return 0;
}


效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐