// 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, , szWstr, -, NULL, , NULL, NULL);
return WideCharToMultiByte(CP_ACP, , szWstr, -, szCstr, iLength, NULL, NULL);
} void OpenDirectoryDialog(HWND hWnd, char directoryPath[], const int32_t directoryPathLen)
{
TCHAR szBuffer[MAX_PATH] = { };
BROWSEINFO bi = { };
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 = ;
char tmpPath[MAX_PATH] = { };
sprintf_s(tmpPath, "%s\\*", directoryPath);
if ((hFile = _findfirst(tmpPath, &fileinfo)) == -){ return; }
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != && strcmp(fileinfo.name, "..") != )
{
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) == );
_findclose(hFile);
} void StringToLower(std::string &str)
{
for (uint32_t i = ; 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 >= )
{
return localFileName.substr(pos);
}
return localFileName;
} void DumpFiles(const std::vector<std::string> &files)
{
for (uint32_t i = ; i < files.size() && i < ; ++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 = ,counter = ;
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 = ;
static char buf[maxBufLen + ];
std::ifstream inFile(fileName, std::ios::in);
if (!inFile){ return ; }
uint32_t counter = ;
while (!inFile.eof())
{
memset(buf, , 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] = { };
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 ;
}

效果图:

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

  1. 用Java实现将多级文件夹下的所有文件统一放到一个文件夹中

    每次下了电影(男生懂得呦),每部电影都放在一个单独的文件夹里,看的时候很是不方便啊,一直重复着进入文件夹.后退,再进.再退的操作,而手动把这些电影全部复制出来又太繁琐.因此为了解决这个问题,用IO写了 ...

  2. php 遍历一个文件夹下的所有文件和子文件

    php 遍历一个文件夹下的所有文件和子文件 <?php /** * 将读取到的目录以数组的形式展现出来 * @return array * opendir() 函数打开一个目录句柄,可由 clo ...

  3. Java基础面试操作题: File IO 文件过滤器FileFilter 练习 把一个文件夹下的.java文件复制到另一个文件夹下的.txt文件

    package com.swift; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File ...

  4. Java遍历一个文件夹下的全部文件

    Java工具中为我们提供了一个用于管理文件系统的类,这个类就是File类,File类与其它流类不同的是,流类关心的是文件的内容.而File类关心的是磁盘上文件的存储. 一,File类有多个构造器,经常 ...

  5. 读取指定文件夹下的全部文件,可通过正则进行过滤,返回文件路径数组 -- 基于node的一个函数

    var fs = require('fs'); // 模板文件夹路径 var templateDirectory = '../src'; //相对于当前文件的相对路径 //var templateDi ...

  6. Java——用程序编译一个文件夹下所有java文件到另一个文件夹下

    package com.java.test.a; import java.io.IOException; import java.util.ArrayList; import java.util.Ar ...

  7. GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级

    一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...

  8. C/C++不同文件夹下包含头文件的方法及#include的使用

    转自:http://blog.sina.com.cn/s/blog_6e0693f70100so42.html 本文主要介绍了如何不同文件夹下使用预处理器指示符#include. 假设我们有如下一个工 ...

  9. 递归输出文件夹下的所有文件的名称(转自 MSDN)

    问题:如何输出给定文件夹目录下面的所有文件的名称? C#代码: using System; using System.IO; namespace MyTest { public class Progr ...

随机推荐

  1. NoSQL-Redis【1】-控制台配置密码

    1.设置密码为123456 CONFIG SET requirepass 123456 2.验证密码 AUTH 123456 3.redis-cli连接 @ECHO OFF redis-cli.exe ...

  2. 【SAP BO】【DI】DataService 服务无法启动。错误1069:由于登录失败而无法启动服务

    重启BI服务器后,突然发现DataServices服务无法启动,提示: 错误 1069:由于登录失败而无法启动服务. 解决方法: (1)打开控制面板--> 服务 --> 右键点击Data ...

  3. 【Linux程序设计】之进程间的通信

    这个系列的博客贴的都是我大二的时候学习Linux系统高级编程时的一些实验程序,都挺简单的. 实验题目:Linux环境下的进程间通信 实验目的:熟悉进程通信中信号概念及信号处理:掌握进程间的管道通信编程 ...

  4. [知识点]平衡树之Splay

    // 此博文为迁移而来,写于2015年7月18日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6rg.html 1.前 ...

  5. 【BZOJ】2697: 特技飞行

    题意 \(k(1 \le k \le 300)\)种物品,价值分别为\(c_i(0 \le c_i \le 1000)\).有\(n(1 \le n \le 1000)\)分钟,每分钟可以选择一个物品 ...

  6. POJ 1279 Art Gallery(半平面交)

    题目链接 回忆了一下,半平面交,整理了一下模版. #include <cstdio> #include <cstring> #include <string> #i ...

  7. 【Java】RuleSource约束常用方法整理

    1-常用约束规则RuleSource的设置方法   例如: addRules(new Rules(ProgramFeeItem.class){ protected void initRules() { ...

  8. BZOJ4546: codechef XRQRS

    Description 给定一个初始时为空的整数序列(元素由1开始标号)以及一些询问: 类型1:在数组后面就加入数字x. 类型2:在区间L…R中找到y,最大化(x xor y). 类型3:删除数组最后 ...

  9. BZOJ4532: [BeiJing2014 WinterCamp] 珠链

    Description Alex喜欢玩网络游戏,认为这是智力和体力的综合锻炼.在一次游戏活动中,他意外获得了一个传说中威力极其强大的法宝:珠链.  珠链,顾名思义,就是由许多小珠子串起来的一条链.珠子 ...

  10. VMwareTools 安装(VMware Player)

    1. VMare Tools 按钮是灰化的,需要对虚拟机做如下设置:(在虚拟机没有启动的状态下进行)     1)Player(P)->管理->虚拟机设置->CD/DVD  选择:使 ...