跨平台的命令行字典外壳 dic.exe
[i=s] 本帖最后由 happy886rr 于 2017-7-10 11:59 编辑 [/i]下载:城通网盘[url]https://page37.ctfile.com/fs/14274637-204821002[/url]
[quote] DIC.EXE是一款字典外壳第三方,已做多平台延伸,代码支持多平台编译,可在windows、linux、安卓、ios等多种设备上运行。查词核心采用自主研发的RODB内存数据库,迄今为止最快的查询速度,查询任何单词耗时都小于1毫秒。RODB意在通过最简短的代码实现最高速的数据查询。
(图片均为外链)(MFC版) 5KB, [attach]10660[/attach]
(安卓版)下载地址:[url]https://page37.ctfile.com/fs/14274637-204820983[/url]
[img]http://i1.piimg.com/1949/7731e9ba0046f705.png[/img]
[/quote]
跨平台源码:[code]/*
CONSOLE ENGLISH-CHINESE DICTIONARY, COPYRIGHT@2017~2019 BY LEO, VERSION 1.0
DIC.EXE
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if !defined(_MSC_VER) && !defined(bool)
#include <stdbool.h>
#endif
/***************定义宏变量***************/
//标准行长
#define BUFF_SIZE 1024
//标准基长
#define UINT_SIZE 4
//索引阈值
#define INDX_SIZE 255*255*UINT_SIZE*4
/***************定义宏函数***************/
//字符串转索引值
#define CHARARRAY2UINT(x) (unsigned int)(((unsigned char)(x)[0]<<24)|((unsigned char)(x)[1]<<16)|((unsigned char)(x)[2]<<8)|((unsigned char)(x)[3]))
//索引值转字符串
#define UINT2CHARARRAY(inSTAINER,uINNUM) \
(inSTAINER)[0] = (char)(((uINNUM)&0xFF000000)>>24),\
(inSTAINER)[1] = (char)(((uINNUM)&0x00FF0000)>>16),\
(inSTAINER)[2] = (char)(((uINNUM)&0x0000FF00)>> 8),\
(inSTAINER)[3] = (char)( (uINNUM)&0x000000FF );
/***************设全局变量***************/
//微型容器
char Keyic[UINT_SIZE];
unsigned char Brray[UINT_SIZE * 4];
//行存容器
char Input[BUFF_SIZE];
char Line [BUFF_SIZE];
char lineCACHE[BUFF_SIZE*16];
//定义RODB数据类型
typedef struct
{
const char* data;
const char* index;
const unsigned int indexnum;
} RODB, *PRODB;
/***************WIN32兼容 ***************/
#if defined(WIN32) || defined(__WIN32__)
//引入WIN32头文件
#include <windows.h>
#include <locale.h>
//缓存容器
wchar_t wcsCACHE[BUFF_SIZE * 32];
char outCACHE[BUFF_SIZE * 32];
//ANSI、UTF8互转函数
char* ANSIteUTF8(const char* inputSTR, int inPAGE, int outPAGE, wchar_t* wcsCACHE, char* outCACHE)
{
//输入代码页 过渡到 UNICODE中转代码页
int wlEN=MultiByteToWideChar(inPAGE, 0, inputSTR,-1, NULL, 0);
MultiByteToWideChar(inPAGE, 0, inputSTR, -1, wcsCACHE, wlEN);
wcsCACHE[wlEN]=L'\0';
//UNICODE中转代码页 过渡到 输出代码页
int uLEN=WideCharToMultiByte(outPAGE, 0, wcsCACHE, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(outPAGE, 0, wcsCACHE, -1, outCACHE, uLEN, NULL, NULL);
outCACHE[uLEN]='\0';
//返回结果
return outCACHE;
}
#endif
/***************功能函数群***************/
//快排回调
int CompUINT(const void* a, const void* b)
{
unsigned int leftINDEX=CHARARRAY2UINT((unsigned char*)a), rightINDEX=CHARARRAY2UINT((unsigned char*)b);
//布尔比较 化解 UINT溢出漏洞
if(leftINDEX <rightINDEX)
{
return -1;
}
return (int)(leftINDEX >rightINDEX);
}
//创建 RODB 内存数据库
RODB CreatRODB(const char* dicDATA_FILE, const char demilCHAR, unsigned char* pBRRAY)
{
//读取字典文件
FILE* fp=fopen(dicDATA_FILE, "rb");
if(fp == NULL)
{
fprintf(stdout, "[ERROR]: read dictionary error\n");
exit(1);
}
//获取字典文件尺寸
fseek(fp, 0, SEEK_END);
int fsize= ftell(fp);
fseek(fp, 0, SEEK_SET);
//动态分配字典容器
char* dicDATA=(char*)malloc(fsize+2);
//将字典文件读入内存
fread(dicDATA, sizeof(char), fsize, fp);
fclose(fp);
dicDATA[fsize]='\n', dicDATA[fsize+1]='\0';
//动态分配索引容器
char* fastINDEX=(char*)malloc(INDX_SIZE), *fastp=fastINDEX;
int lpHEAD, indexCOUNT=0, preINDEX_OFFSET=0, perINDEX_OFFLEN=0;
unsigned int preINDEX=(unsigned int)0, curINDEX=(unsigned int)0;
bool needsQSORT=false;
char* lp=NULL, *cp=(char*)dicDATA;
while(*cp != '\0')
{
lpHEAD=(int)(char*)cp, lp=(char*)Line;
//读取关键词KEY:分隔符前字串
while((*cp != '\n') && (*cp != demilCHAR))
{
*lp++ = *cp++;
};
*lp='\0';
//数据指针 置 流位 换行符
while(*cp++ != '\n');
//提取 关键词KEY 前4字符
strncpy((char*)pBRRAY, Line, UINT_SIZE);
//根据 KEY前4字符 创建索引
curINDEX=CHARARRAY2UINT(pBRRAY);
//效验索引可行性
if(curINDEX < preINDEX)
{
//如果逆序,则启用QSORT快排
needsQSORT=true;
}
//比对索引
if(curINDEX != preINDEX)
{
//打印索引值
//fprintf(stdout, "%u %s\n", curINDEX, Line);
int ILEN=lpHEAD-preINDEX_OFFSET, IOFFSET=lpHEAD-(int)(char*)dicDATA;
if(fastp != fastINDEX)
{
//尺度码块
UINT2CHARARRAY(fastp, (unsigned int)ILEN);
fastp+=4;
}
//索引码块
UINT2CHARARRAY(fastp, (unsigned int)curINDEX);
indexCOUNT++;
fastp+=4;
//效验码块
UINT2CHARARRAY(fastp, (unsigned int)0);
fastp+=4;
//偏移码块
UINT2CHARARRAY(fastp, (unsigned int)IOFFSET);
fastp+=4;
preINDEX=curINDEX;
preINDEX_OFFSET=lpHEAD;
}
}
int lastOFFSET=(int)(char*)dicDATA+fsize-preINDEX_OFFSET;
if(fastp != fastINDEX)
{
//追加结尾尺度码块
UINT2CHARARRAY(fastp, (unsigned int)lastOFFSET);
fastp+=4;
}
//置结束符
*fastp='\0';
//启用快排索引
if(needsQSORT)
{
qsort((void*)fastINDEX, (size_t)indexCOUNT, (size_t)UINT_SIZE * 4, CompUINT);
}
RODB ret = {(const char*)dicDATA, (const char*)fastINDEX, (const unsigned int)indexCOUNT};
//返回RODB指针
return ret;
}
//高速查询核心
bool SearchResultCharArray(PRODB prodb, unsigned int uSEARCH_INDEX, unsigned char* pBRRAY, char* lineCACHE, char* Line, char* srcKEY)
{
//使用闭区间
int i, minIDX = -1, maxIDX = (unsigned int)(prodb->indexnum);
unsigned iSEARCH_INDEX;
bool bret=false;
while(maxIDX - minIDX > 1)
{
i = (maxIDX + minIDX)>>1;
//读取字典索引值
memcpy(pBRRAY, &((prodb->index)[UINT_SIZE * 4 * i]), UINT_SIZE * 4);
iSEARCH_INDEX = CHARARRAY2UINT(pBRRAY);
//找到目标索引
if(iSEARCH_INDEX == uSEARCH_INDEX)
{
break;
}
//更新搜索范围
(iSEARCH_INDEX < uSEARCH_INDEX) ?(minIDX = i) :(maxIDX = i);
}
//如果搜索不到,则退出
if(iSEARCH_INDEX != uSEARCH_INDEX)
{
//查询失败
return bret;
}
//获取 KEY 在字典数据库中的偏移
unsigned int keyOFFSET = CHARARRAY2UINT(pBRRAY+UINT_SIZE*2), keyOFFLEN=CHARARRAY2UINT(pBRRAY+UINT_SIZE*3);
//转到KEY偏移位置,复制 keyOFFLEN长度数据 至 行缓存容器
memcpy(lineCACHE, &((prodb->data)[keyOFFSET]), keyOFFLEN);
//置容器结束符
lineCACHE[keyOFFLEN]='\0';
//显示查询结果
char* bp = (char*)lineCACHE;
int keyLEN = strlen(srcKEY);
while(*bp)
{
char* p=Line;
while((*p++ = *bp++) != '\n');
*p='\0';
if(strncmp(Line, srcKEY, keyLEN) == 0)
{
//设置查询真值
bret = true;
//行显查询结果
#if defined(WIN32) || defined(__WIN32__)
fprintf(stdout, "%s", ANSIteUTF8(Line, CP_UTF8, CP_ACP, wcsCACHE, outCACHE));
#else
fprintf(stdout, "%s", Line);
#endif
}
}
//返还查询真值
return bret;
}
//*************MAIN主函数入口*************/
int main(int argc, char** argv)
{
if(argc != 2)
{
fprintf(stdout, "Usage: dic [Dictionary file]\n");
return 1;
}
//打印字典标题
fprintf(stdout, "[English-Chinese dictionary] --- use \"q\" to exit");
//构建RODB内存数据库
unsigned char* pBRRAY=(unsigned char*)Brray;
RODB rodb=CreatRODB(argv[1], '\t', pBRRAY);
//构建字典查询 SHELL
while(printf("\n>>"), fgets(Input, BUFF_SIZE-1, stdin)!=NULL)
{
//将输入转化为字符串
char *p =strchr(Input,'\n');
if(p != NULL)
{
*p='\0';
}
//判断输入是否为空
if (p!=Input)
{
//使用按键 小写q 退出
if(!strcmp(Input, "q"))
{
fputs("[EXIT]: thanks for use, bye!", stdout);
break;
}
#if defined(WIN32) || defined(__WIN32__)
//对WIN32控制台 代码页 兼容
char* srcKEY=ANSIteUTF8(Input, CP_ACP, CP_UTF8, wcsCACHE, outCACHE);
#else
char* srcKEY=Input;
#endif
//将被查询字符串转化为索引值
strncpy(Keyic, srcKEY, UINT_SIZE);
unsigned int uSEARCH_INDEX = CHARARRAY2UINT(Keyic);
//执行查询
if(! SearchResultCharArray(&rodb, uSEARCH_INDEX, pBRRAY, lineCACHE, Line, srcKEY) )
{
fprintf(stdout, "[SORRY]: can not find it\n");
}
}
}
return 0;
}
[/code]补充:附带几个移植到手机上的第三方,手机上的控制台一样精彩。包括:bse、choice、dic、equation、revpolish。下载地址:[url]https://page37.ctfile.com/fs/14274637-204820983[/url] [i=s] 本帖最后由 老刘1号 于 2017-6-2 22:57 编辑 [/i]
希望出GUI版 [i=s] 本帖最后由 happy886rr 于 2017-6-2 12:51 编辑 [/i]
[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=199971&ptid=44336]2#[/url] [i]老刘1号[/i] [/b]已更新MFC版,窗口取词,更加速度。 [b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=199973&ptid=44336]3#[/url] [i]happy886rr[/i] [/b]
命令行版提示找不到词典,在程序目录或者工作目录下都不行,词典的名称没有更改
页:
[1]