Board logo

标题: 跨平台的命令行字典外壳 dic.exe [打印本页]

作者: happy886rr    时间: 2017-5-31 02:47     标题: 跨平台的命令行字典外壳 dic.exe

下载:城通网盘https://page37.ctfile.com/fs/14274637-204821002
DIC.EXE是一款字典外壳第三方,已做多平台延伸,代码支持多平台编译,可在windows、linux、安卓、ios等多种设备上运行。查词核心采用自主研发的RODB内存数据库,迄今为止最快的查询速度,查询任何单词耗时都小于1毫秒。RODB意在通过最简短的代码实现最高速的数据查询。
(图片均为外链)(MFC版) 5KB
链接: https://pan.baidu.com/s/10vFlaopRogWbFl4xozOMtA?pwd=i3ij

(安卓版)下载地址:https://page37.ctfile.com/fs/14274637-204820983


跨平台源码:
  1. /*
  2. CONSOLE ENGLISH-CHINESE DICTIONARY, COPYRIGHT@2017~2019 BY LEO, VERSION 1.0
  3. DIC.EXE
  4. */
  5. #include   <stdio.h>
  6. #include  <stdlib.h>
  7. #include  <string.h>
  8. #include    <time.h>
  9. #if !defined(_MSC_VER) && !defined(bool)
  10. #include <stdbool.h>
  11. #endif
  12. /***************定义宏变量***************/
  13. //标准行长
  14. #define BUFF_SIZE 1024
  15. //标准基长
  16. #define UINT_SIZE 4
  17. //索引阈值
  18. #define INDX_SIZE 255*255*UINT_SIZE*4
  19. /***************定义宏函数***************/
  20. //字符串转索引值
  21. #define CHARARRAY2UINT(x) (unsigned int)(((unsigned char)(x)[0]<<24)|((unsigned char)(x)[1]<<16)|((unsigned char)(x)[2]<<8)|((unsigned char)(x)[3]))
  22. //索引值转字符串
  23. #define UINT2CHARARRAY(inSTAINER,uINNUM) \
  24. (inSTAINER)[0] = (char)(((uINNUM)&0xFF000000)>>24),\
  25. (inSTAINER)[1] = (char)(((uINNUM)&0x00FF0000)>>16),\
  26. (inSTAINER)[2] = (char)(((uINNUM)&0x0000FF00)>> 8),\
  27. (inSTAINER)[3] = (char)( (uINNUM)&0x000000FF     );
  28. /***************设全局变量***************/
  29. //微型容器
  30. char          Keyic[UINT_SIZE];
  31. unsigned char Brray[UINT_SIZE * 4];
  32. //行存容器
  33. char Input[BUFF_SIZE];
  34. char Line [BUFF_SIZE];
  35. char lineCACHE[BUFF_SIZE*16];
  36. //定义RODB数据类型
  37. typedef struct
  38. {
  39. const char* data;
  40. const char* index;
  41. const unsigned int indexnum;
  42. } RODB, *PRODB;
  43. /***************WIN32兼容 ***************/
  44. #if defined(WIN32) || defined(__WIN32__)
  45. //引入WIN32头文件
  46. #include <windows.h>
  47. #include  <locale.h>
  48. //缓存容器
  49. wchar_t wcsCACHE[BUFF_SIZE * 32];
  50. char    outCACHE[BUFF_SIZE * 32];
  51. //ANSI、UTF8互转函数
  52. char* ANSIteUTF8(const char* inputSTR, int inPAGE, int outPAGE, wchar_t* wcsCACHE, char* outCACHE)
  53. {
  54. //输入代码页 过渡到 UNICODE中转代码页
  55. int wlEN=MultiByteToWideChar(inPAGE, 0, inputSTR,-1, NULL, 0);
  56. MultiByteToWideChar(inPAGE, 0, inputSTR, -1, wcsCACHE, wlEN);
  57. wcsCACHE[wlEN]=L'\0';
  58. //UNICODE中转代码页 过渡到 输出代码页
  59. int uLEN=WideCharToMultiByte(outPAGE, 0, wcsCACHE, -1, NULL, 0, NULL, NULL);
  60. WideCharToMultiByte(outPAGE, 0, wcsCACHE, -1, outCACHE, uLEN, NULL, NULL);
  61. outCACHE[uLEN]='\0';
  62. //返回结果
  63. return outCACHE;
  64. }
  65. #endif
  66. /***************功能函数群***************/
  67. //快排回调
  68. int CompUINT(const void* a, const void* b)
  69. {
  70. unsigned int leftINDEX=CHARARRAY2UINT((unsigned char*)a), rightINDEX=CHARARRAY2UINT((unsigned char*)b);
  71. //布尔比较 化解 UINT溢出漏洞
  72. if(leftINDEX <rightINDEX)
  73. {
  74. return -1;
  75. }
  76. return (int)(leftINDEX >rightINDEX);
  77. }
  78. //创建 RODB 内存数据库
  79. RODB CreatRODB(const char* dicDATA_FILE, const char demilCHAR, unsigned char* pBRRAY)
  80. {
  81. //读取字典文件
  82. FILE* fp=fopen(dicDATA_FILE, "rb");
  83. if(fp == NULL)
  84. {
  85. fprintf(stdout, "[ERROR]: read dictionary error\n");
  86. exit(1);
  87. }
  88. //获取字典文件尺寸
  89. fseek(fp, 0, SEEK_END);
  90. int fsize= ftell(fp);
  91. fseek(fp, 0, SEEK_SET);
  92. //动态分配字典容器
  93. char* dicDATA=(char*)malloc(fsize+2);
  94. //将字典文件读入内存
  95. fread(dicDATA, sizeof(char), fsize, fp);
  96. fclose(fp);
  97. dicDATA[fsize]='\n', dicDATA[fsize+1]='\0';
  98. //动态分配索引容器
  99. char* fastINDEX=(char*)malloc(INDX_SIZE), *fastp=fastINDEX;
  100. int lpHEAD, indexCOUNT=0, preINDEX_OFFSET=0, perINDEX_OFFLEN=0;
  101. unsigned int preINDEX=(unsigned int)0, curINDEX=(unsigned int)0;
  102. bool needsQSORT=false;
  103. char* lp=NULL, *cp=(char*)dicDATA;
  104. while(*cp != '\0')
  105. {
  106. lpHEAD=(int)(char*)cp, lp=(char*)Line;
  107. //读取关键词KEY:分隔符前字串
  108. while((*cp != '\n') && (*cp != demilCHAR))
  109. {
  110. *lp++ = *cp++;
  111. };
  112. *lp='\0';
  113. //数据指针 置 流位 换行符
  114. while(*cp++ != '\n');
  115. //提取 关键词KEY 前4字符
  116. strncpy((char*)pBRRAY, Line, UINT_SIZE);
  117. //根据 KEY前4字符 创建索引
  118. curINDEX=CHARARRAY2UINT(pBRRAY);
  119. //效验索引可行性
  120. if(curINDEX < preINDEX)
  121. {
  122. //如果逆序,则启用QSORT快排
  123. needsQSORT=true;
  124. }
  125. //比对索引
  126. if(curINDEX != preINDEX)
  127. {
  128. //打印索引值
  129. //fprintf(stdout, "%u %s\n", curINDEX, Line);
  130. int ILEN=lpHEAD-preINDEX_OFFSET, IOFFSET=lpHEAD-(int)(char*)dicDATA;
  131. if(fastp != fastINDEX)
  132. {
  133. //尺度码块
  134. UINT2CHARARRAY(fastp, (unsigned int)ILEN);
  135. fastp+=4;
  136. }
  137. //索引码块
  138. UINT2CHARARRAY(fastp, (unsigned int)curINDEX);
  139. indexCOUNT++;
  140. fastp+=4;
  141. //效验码块
  142. UINT2CHARARRAY(fastp, (unsigned int)0);
  143. fastp+=4;
  144. //偏移码块
  145. UINT2CHARARRAY(fastp, (unsigned int)IOFFSET);
  146. fastp+=4;
  147. preINDEX=curINDEX;
  148. preINDEX_OFFSET=lpHEAD;
  149. }
  150. }
  151. int lastOFFSET=(int)(char*)dicDATA+fsize-preINDEX_OFFSET;
  152. if(fastp != fastINDEX)
  153. {
  154. //追加结尾尺度码块
  155. UINT2CHARARRAY(fastp, (unsigned int)lastOFFSET);
  156. fastp+=4;
  157. }
  158. //置结束符
  159. *fastp='\0';
  160. //启用快排索引
  161. if(needsQSORT)
  162. {
  163. qsort((void*)fastINDEX, (size_t)indexCOUNT, (size_t)UINT_SIZE * 4, CompUINT);
  164. }
  165. RODB ret = {(const char*)dicDATA, (const char*)fastINDEX, (const unsigned int)indexCOUNT};
  166. //返回RODB指针
  167. return ret;
  168. }
  169. //高速查询核心
  170. bool SearchResultCharArray(PRODB prodb, unsigned int uSEARCH_INDEX, unsigned char* pBRRAY, char* lineCACHE, char* Line, char* srcKEY)
  171. {
  172. //使用闭区间
  173. int i, minIDX = -1, maxIDX = (unsigned int)(prodb->indexnum);
  174. unsigned iSEARCH_INDEX;
  175. bool bret=false;
  176. while(maxIDX - minIDX > 1)
  177. {
  178. i = (maxIDX + minIDX)>>1;
  179. //读取字典索引值
  180. memcpy(pBRRAY, &((prodb->index)[UINT_SIZE * 4 * i]), UINT_SIZE * 4);
  181. iSEARCH_INDEX = CHARARRAY2UINT(pBRRAY);
  182. //找到目标索引
  183. if(iSEARCH_INDEX == uSEARCH_INDEX)
  184. {
  185. break;
  186. }
  187. //更新搜索范围
  188. (iSEARCH_INDEX  < uSEARCH_INDEX) ?(minIDX = i) :(maxIDX = i);
  189. }
  190. //如果搜索不到,则退出
  191. if(iSEARCH_INDEX != uSEARCH_INDEX)
  192. {
  193. //查询失败
  194. return bret;
  195. }
  196. //获取 KEY 在字典数据库中的偏移
  197. unsigned int keyOFFSET = CHARARRAY2UINT(pBRRAY+UINT_SIZE*2), keyOFFLEN=CHARARRAY2UINT(pBRRAY+UINT_SIZE*3);
  198. //转到KEY偏移位置,复制 keyOFFLEN长度数据 至 行缓存容器
  199. memcpy(lineCACHE, &((prodb->data)[keyOFFSET]), keyOFFLEN);
  200. //置容器结束符
  201. lineCACHE[keyOFFLEN]='\0';
  202. //显示查询结果
  203. char* bp = (char*)lineCACHE;
  204. int keyLEN = strlen(srcKEY);
  205. while(*bp)
  206. {
  207. char* p=Line;
  208. while((*p++ = *bp++) != '\n');
  209. *p='\0';
  210. if(strncmp(Line, srcKEY, keyLEN) == 0)
  211. {
  212. //设置查询真值
  213. bret = true;
  214. //行显查询结果
  215. #if defined(WIN32) || defined(__WIN32__)
  216. fprintf(stdout, "%s", ANSIteUTF8(Line, CP_UTF8, CP_ACP, wcsCACHE, outCACHE));
  217. #else
  218. fprintf(stdout, "%s", Line);
  219. #endif
  220. }
  221. }
  222. //返还查询真值
  223. return bret;
  224. }
  225. //*************MAIN主函数入口*************/
  226. int main(int argc, char** argv)
  227. {
  228. if(argc != 2)
  229. {
  230. fprintf(stdout, "Usage: dic [Dictionary file]\n");
  231. return 1;
  232. }
  233. //打印字典标题
  234. fprintf(stdout, "[English-Chinese dictionary] --- use \"q\" to exit");
  235. //构建RODB内存数据库
  236. unsigned char* pBRRAY=(unsigned char*)Brray;
  237. RODB rodb=CreatRODB(argv[1], '\t', pBRRAY);
  238. //构建字典查询 SHELL
  239. while(printf("\n>>"), fgets(Input, BUFF_SIZE-1, stdin)!=NULL)
  240. {
  241. //将输入转化为字符串
  242. char *p =strchr(Input,'\n');
  243. if(p != NULL)
  244. {
  245. *p='\0';
  246. }
  247. //判断输入是否为空
  248. if (p!=Input)
  249. {
  250. //使用按键 小写q 退出
  251. if(!strcmp(Input, "q"))
  252. {
  253. fputs("[EXIT]: thanks for use, bye!", stdout);
  254. break;
  255. }
  256. #if defined(WIN32) || defined(__WIN32__)
  257. //对WIN32控制台 代码页 兼容
  258. char* srcKEY=ANSIteUTF8(Input, CP_ACP, CP_UTF8, wcsCACHE, outCACHE);
  259. #else
  260. char* srcKEY=Input;
  261. #endif
  262. //将被查询字符串转化为索引值
  263. strncpy(Keyic, srcKEY, UINT_SIZE);
  264. unsigned int uSEARCH_INDEX = CHARARRAY2UINT(Keyic);
  265. //执行查询
  266. if(! SearchResultCharArray(&rodb, uSEARCH_INDEX, pBRRAY, lineCACHE, Line, srcKEY) )
  267. {
  268. fprintf(stdout, "[SORRY]: can not find it\n");
  269. }
  270. }
  271. }
  272. return 0;
  273. }
复制代码
补充:附带几个移植到手机上的第三方,手机上的控制台一样精彩。包括:bse、choice、dic、equation、revpolish。下载地址:https://page37.ctfile.com/fs/14274637-204820983
作者: 老刘1号    时间: 2017-5-31 12:25

本帖最后由 老刘1号 于 2017-6-2 22:57 编辑

希望出GUI版
作者: happy886rr    时间: 2017-5-31 13:29

本帖最后由 happy886rr 于 2017-6-2 12:51 编辑

回复 2# 老刘1号 已更新MFC版,窗口取词,更加速度。
作者: 老刘1号    时间: 2017-6-2 13:17

回复 3# happy886rr


    命令行版提示找不到词典,在程序目录或者工作目录下都不行,词典的名称没有更改




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2