一.项目原因
Linux下有功能强大的find命令,而windows下文件夹框下的默认搜索是搜索时再进行暴力遍历查找,非常的慢。
所以做一个类似everything的搜索软件来进行搜索目的。
二.项目需求
- 文档普通搜索
- 拼音全拼搜索
- 拼音首字母搜索
- 搜索关键字高亮显示
三.开发环境
1.编译器 : VS2013 / 控制应用平台
2.编程语言 : C++ / C++11
2.数据库 : sqlite3
4.项目涉及的知识点
- 数据库操作:(sqlite安装,创建数据库,创建表,插入数据,删除数据,创建索引,查询数据 (条件查询、 模糊查询))
- 静态库和动态库:静态库和动态的制作,动态库和动态的使用
- 设计模式(单例模式)
- 多线程同步机制(互斥量)
- 日志
- 汉字与拼音的转换
三.项目实现
公共模块
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<set>
#include<stdarg.h>
#include<windows.h>
#include<io.h>
#include<thread>
#include<chrono>
#include<algorithm>
#include<mutex>
#include<condition_variable>
#define MAX_SQL_SIZE 256
#define MAX_BUF_SIZE 128
系统工具模块
#pragma once
#include"Common.h"
#ifndef __TRACE__
//#define __TRACE__
#endif
#ifndef __DEBUG__
//#define __DEBUG__
#endif
///
static std::string GetFileName(const std::string& path)
{
char ch = '/'; //Linux
#ifdef _WIN32
ch = '\\';
#endif
size_t pos = path.rfind(ch);
if (pos == std::string::npos)
return path;
else
return path.substr(pos + 1);
}
//用于调试追溯的trace log
inline static void __TraceDebug(const char* filename, int line, const char* function, const char* format, ...)
{
#ifdef __TRACE__
//输出调用函数的信息
fprintf(stdout, "[TRACE][%s:%d:%s]:", GetFileName(filename).c_str(), line, function);
//可变参数
//输出用户打的trace信息
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, "\n");
#endif
}
inline static void __ErrorDebug(const char* filename, int line, const char* function, const char* format, ...)
{
#ifdef __DEBUG__
//输出调用函数的信息
fprintf(stdout, "[ERROR][%s:%d:%s]:", GetFileName(filename).c_str(), line, function);
//输出用户打的trace信息
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, " errmsg:%s, errno:%d\n", strerror(errno), errno);
#endif
}
#define TRACE_LOG(...) \
__TraceDebug(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__);
#define ERROR_LOG(...) \
__ErrorDebug(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__);
//界面模块
#define WIDTH 120
#define HEIGHT 30
void SetCurPos(int x, int y); //x 带表界面的行 y 代表界面的列
void HideCursor();
void DrawCol(int x, int y);
void DrawRow(int x, int y);
void DrawFrame(char *title);
void DrawMenu();
void SystemEnd();
/
//获取文件个数
size_t GetFileCount(const string &path);
//目录监控函数
bool DirectoryWatch(const string &path);
//系统功能函数模块
void DirectoryList(const string &path, vector<string> &subfile, vector<string> &subdir);
// 汉字转拼音全拼
/* CSDN:http://blog.csdn.net/csnd_ayo */
string ChineseConvertPinYinAllSpell(const string& dest_chinese);
// 汉字转拼音首字母
string ChineseConvertPinYinInitials(const string& name);
// 颜色高亮显示一段字符串
void ColourPrintf(const string &str);
#define _CRT_SECURE_NO_WARNINGS 1
#include"Sysutil.h"
//设置光标位置
void SetCurPos(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = {
y, x };
SetConsoleCursorPosition(handle, pos);
}
//隐藏光标
void HideCursor()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info = {
100, 0 };
SetConsoleCursorInfo(handle, &cursor_info);
}
//画列 ||
void DrawCol(int x, int y)
{
for (int i = 0; i<HEIGHT; ++i)
{
SetCurPos(x + i, y);
printf("||");
}
}
//画行 =
void DrawRow(int x, int y)
{
for (int i = 0; i<WIDTH - 4; ++i)
{
SetCurPos(x, y + i);
printf("=");
}
}
void SystemEnd()
{
SetCurPos(HEIGHT - 1, (WIDTH - 4 - strlen("请按任意键继续 . . .")) / 2);
}
//画系统框架界面
void DrawFrame(char *title)
{
//设置标题
char buf[MAX_BUF_SIZE] = {
0 };
sprintf(buf, "title %s", title);
system(buf);
//设置界面的宽度和高度
memset(buf, 0, MAX_BUF_SIZE);
sprintf(buf, "mode con cols=%d lines=%d", WIDTH, HEIGHT);
system(buf);
//设置颜色
//设置系统界面
DrawCol(0, 0); //左边列
DrawCol(0, WIDTH - 2); //右边列
DrawRow(0, 2);
DrawRow(2, 2);
DrawRow(4, 2);
DrawRow(HEIGHT - 6, 2);
DrawRow(HEIGHT - 4, 2);
DrawRow(HEIGHT - 2, 2);
}
extern char *title;
void DrawMenu()
{
//设置标题
SetCurPos(1, (WIDTH - 4 - strlen(title)) / 2);
printf("%s", title);
//设置名称 路径
SetCurPos(3, 2);
printf("%-30s%-85s", "名称", "路径");
//设置 exit 退出系统
SetCurPos(HEIGHT - 3, (WIDTH - 4 - strlen("exit 退出系统 .")) / 2);
printf("%s", "exit 退出系统 .");
//设置 输入:>
SetCurPos(HEIGHT - 5, 2);
printf("%s", "请输入:>");
}
//
extern size_t g_FileCount;
extern size_t g_ScanCount;
size_t GetFileCount(const string &path)
{
string _path = path + "\\" + "*.*";
struct _finddata_t fileAttri;
long handle = _findfirst(_path.c_str(), &fileAttri);
if (handle == -1)
return 0;
do
{
if (fileAttri.name[0] == '.')
continue;
g_ScanCount++;
if (fileAttri.attrib & _A_SUBDIR)
GetFileCount(path + "\\" + fileAttri.name);
} while (_findnext(handle, &fileAttri) == 0);
return g_ScanCount;
}
bool DirectoryWatch(const string &path)
{
size_t file_count = GetFileCount(path);
return file_count != g_FileCount;
}
// 汉字转拼音全拼
/* CSDN:http://blog.csdn.net/csnd_ayo */
string ChineseConvertPinYinAllSpell(const string& dest_chinese)
{
static const int spell_value[] =
{
-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032, -20026,
-20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728,
-19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -