找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 18152|回复: 3

跨平台的命令行字典外壳 dic.exe

[复制链接]
发表于 2017-5-31 02:47:03 | 显示全部楼层 |阅读模式
下载:城通网盘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.        
  72.         //布尔比较 化解 UINT溢出漏洞
  73.         if(leftINDEX <rightINDEX)
  74.         {
  75.                 return -1;
  76.         }
  77.         return (int)(leftINDEX >rightINDEX);
  78. }

  79. //创建 RODB 内存数据库
  80. RODB CreatRODB(const char* dicDATA_FILE, const char demilCHAR, unsigned char* pBRRAY)
  81. {
  82.         //读取字典文件
  83.         FILE* fp=fopen(dicDATA_FILE, "rb");
  84.         if(fp == NULL)
  85.         {
  86.                 fprintf(stdout, "[ERROR]: read dictionary error\n");
  87.                 exit(1);
  88.         }

  89.         //获取字典文件尺寸
  90.         fseek(fp, 0, SEEK_END);
  91.         int fsize= ftell(fp);
  92.         fseek(fp, 0, SEEK_SET);

  93.         //动态分配字典容器
  94.         char* dicDATA=(char*)malloc(fsize+2);

  95.         //将字典文件读入内存
  96.         fread(dicDATA, sizeof(char), fsize, fp);
  97.         fclose(fp);
  98.         dicDATA[fsize]='\n', dicDATA[fsize+1]='\0';

  99.         //动态分配索引容器
  100.         char* fastINDEX=(char*)malloc(INDX_SIZE), *fastp=fastINDEX;

  101.         int lpHEAD, indexCOUNT=0, preINDEX_OFFSET=0, perINDEX_OFFLEN=0;
  102.         unsigned int preINDEX=(unsigned int)0, curINDEX=(unsigned int)0;

  103.         bool needsQSORT=false;
  104.         char* lp=NULL, *cp=(char*)dicDATA;
  105.         while(*cp != '\0')
  106.         {
  107.                 lpHEAD=(int)(char*)cp, lp=(char*)Line;

  108.                 //读取关键词KEY:分隔符前字串
  109.                 while((*cp != '\n') && (*cp != demilCHAR))
  110.                 {
  111.                         *lp++ = *cp++;
  112.                 };
  113.                 *lp='\0';

  114.                 //数据指针 置 流位 换行符
  115.                 while(*cp++ != '\n');

  116.                 //提取 关键词KEY 前4字符
  117.                 strncpy((char*)pBRRAY, Line, UINT_SIZE);

  118.                 //根据 KEY前4字符 创建索引
  119.                 curINDEX=CHARARRAY2UINT(pBRRAY);

  120.                 //效验索引可行性
  121.                 if(curINDEX < preINDEX)
  122.                 {
  123.                         //如果逆序,则启用QSORT快排
  124.                         needsQSORT=true;
  125.                 }

  126.                 //比对索引
  127.                 if(curINDEX != preINDEX)
  128.                 {
  129.                         //打印索引值
  130.                         //fprintf(stdout, "%u %s\n", curINDEX, Line);

  131.                         int ILEN=lpHEAD-preINDEX_OFFSET, IOFFSET=lpHEAD-(int)(char*)dicDATA;
  132.                         if(fastp != fastINDEX)
  133.                         {
  134.                                 //尺度码块
  135.                                 UINT2CHARARRAY(fastp, (unsigned int)ILEN);
  136.                                 fastp+=4;
  137.                         }

  138.                         //索引码块
  139.                         UINT2CHARARRAY(fastp, (unsigned int)curINDEX);
  140.                         indexCOUNT++;
  141.                         fastp+=4;

  142.                         //效验码块
  143.                         UINT2CHARARRAY(fastp, (unsigned int)0);
  144.                         fastp+=4;

  145.                         //偏移码块
  146.                         UINT2CHARARRAY(fastp, (unsigned int)IOFFSET);
  147.                         fastp+=4;

  148.                         preINDEX=curINDEX;
  149.                         preINDEX_OFFSET=lpHEAD;
  150.                 }
  151.         }

  152.         int lastOFFSET=(int)(char*)dicDATA+fsize-preINDEX_OFFSET;

  153.         if(fastp != fastINDEX)
  154.         {
  155.                 //追加结尾尺度码块
  156.                 UINT2CHARARRAY(fastp, (unsigned int)lastOFFSET);
  157.                 fastp+=4;
  158.         }

  159.         //置结束符
  160.         *fastp='\0';

  161.         //启用快排索引
  162.         if(needsQSORT)
  163.         {
  164.                 qsort((void*)fastINDEX, (size_t)indexCOUNT, (size_t)UINT_SIZE * 4, CompUINT);
  165.         }

  166.         RODB ret = {(const char*)dicDATA, (const char*)fastINDEX, (const unsigned int)indexCOUNT};

  167.         //返回RODB指针
  168.         return ret;
  169. }

  170. //高速查询核心
  171. bool SearchResultCharArray(PRODB prodb, unsigned int uSEARCH_INDEX, unsigned char* pBRRAY, char* lineCACHE, char* Line, char* srcKEY)
  172. {
  173.         //使用闭区间
  174.         int i, minIDX = -1, maxIDX = (unsigned int)(prodb->indexnum);
  175.         unsigned iSEARCH_INDEX;
  176.         bool bret=false;

  177.         while(maxIDX - minIDX > 1)
  178.         {
  179.                 i = (maxIDX + minIDX)>>1;

  180.                 //读取字典索引值
  181.                 memcpy(pBRRAY, &((prodb->index)[UINT_SIZE * 4 * i]), UINT_SIZE * 4);
  182.                 iSEARCH_INDEX = CHARARRAY2UINT(pBRRAY);

  183.                 //找到目标索引
  184.                 if(iSEARCH_INDEX == uSEARCH_INDEX)
  185.                 {
  186.                         break;
  187.                 }

  188.                 //更新搜索范围
  189.                 (iSEARCH_INDEX  < uSEARCH_INDEX) ?(minIDX = i) :(maxIDX = i);
  190.         }

  191.         //如果搜索不到,则退出
  192.         if(iSEARCH_INDEX != uSEARCH_INDEX)
  193.         {
  194.                 //查询失败
  195.                 return bret;
  196.         }

  197.         //获取 KEY 在字典数据库中的偏移
  198.         unsigned int keyOFFSET = CHARARRAY2UINT(pBRRAY+UINT_SIZE*2), keyOFFLEN=CHARARRAY2UINT(pBRRAY+UINT_SIZE*3);

  199.         //转到KEY偏移位置,复制 keyOFFLEN长度数据 至 行缓存容器
  200.         memcpy(lineCACHE, &((prodb->data)[keyOFFSET]), keyOFFLEN);

  201.         //置容器结束符
  202.         lineCACHE[keyOFFLEN]='\0';

  203.         //显示查询结果
  204.         char* bp = (char*)lineCACHE;
  205.         int keyLEN = strlen(srcKEY);

  206.         while(*bp)
  207.         {
  208.                 char* p=Line;
  209.                 while((*p++ = *bp++) != '\n');
  210.                 *p='\0';

  211.                 if(strncmp(Line, srcKEY, keyLEN) == 0)
  212.                 {
  213.                         //设置查询真值
  214.                         bret = true;

  215.                         //行显查询结果
  216. #if defined(WIN32) || defined(__WIN32__)

  217.                         fprintf(stdout, "%s", ANSIteUTF8(Line, CP_UTF8, CP_ACP, wcsCACHE, outCACHE));

  218. #else

  219.                         fprintf(stdout, "%s", Line);

  220. #endif
  221.                 }
  222.         }

  223.         //返还查询真值
  224.         return bret;
  225. }

  226. //*************MAIN主函数入口*************/
  227. int main(int argc, char** argv)
  228. {
  229.         if(argc != 2)
  230.         {
  231.                 fprintf(stdout, "Usage: dic [Dictionary file]\n");
  232.                 return 1;
  233.         }

  234.         //打印字典标题
  235.         fprintf(stdout, "[English-Chinese dictionary] --- use "q" to exit");

  236.         //构建RODB内存数据库
  237.         unsigned char* pBRRAY=(unsigned char*)Brray;
  238.         RODB rodb=CreatRODB(argv[1], '\t', pBRRAY);

  239.         //构建字典查询 SHELL
  240.         while(printf("\n>>"), fgets(Input, BUFF_SIZE-1, stdin)!=NULL)
  241.         {
  242.                 //将输入转化为字符串
  243.                 char *p =strchr(Input,'\n');
  244.                 if(p != NULL)
  245.                 {
  246.                         *p='\0';
  247.                 }

  248.                 //判断输入是否为空
  249.                 if (p!=Input)
  250.                 {
  251.                         //使用按键 小写q 退出
  252.                         if(!strcmp(Input, "q"))
  253.                         {
  254.                                 fputs("[EXIT]: thanks for use, bye!", stdout);
  255.                                 break;
  256.                         }

  257. #if defined(WIN32) || defined(__WIN32__)
  258.                         //对WIN32控制台 代码页 兼容
  259.                         char* srcKEY=ANSIteUTF8(Input, CP_ACP, CP_UTF8, wcsCACHE, outCACHE);

  260. #else

  261.                         char* srcKEY=Input;

  262. #endif

  263.                         //将被查询字符串转化为索引值
  264.                         strncpy(Keyic, srcKEY, UINT_SIZE);
  265.                         unsigned int uSEARCH_INDEX = CHARARRAY2UINT(Keyic);

  266.                         //执行查询
  267.                         if(! SearchResultCharArray(&rodb, uSEARCH_INDEX, pBRRAY, lineCACHE, Line, srcKEY) )
  268.                         {
  269.                                 fprintf(stdout, "[SORRY]: can not find it\n");
  270.                         }

  271.                 }
  272.         }
  273.         return 0;
  274. }
复制代码
补充:附带几个移植到手机上的第三方,手机上的控制台一样精彩。包括:bse、choice、dic、equation、revpolish。下载地址:https://page37.ctfile.com/fs/14274637-204820983

评分

参与人数 2技术 +2 收起 理由
523066680 + 1 holy high
老刘1号 + 1 6爆了

查看全部评分

发表于 2017-5-31 12:25:30 | 显示全部楼层
本帖最后由 老刘1号 于 2017-6-2 22:57 编辑

希望出GUI版
 楼主| 发表于 2017-5-31 13:29:09 | 显示全部楼层
本帖最后由 happy886rr 于 2017-6-2 12:51 编辑

回复 2# 老刘1号 已更新MFC版,窗口取词,更加速度。

评分

参与人数 1技术 +1 收起 理由
老刘1号 + 1 6

查看全部评分

发表于 2017-6-2 13:17:47 | 显示全部楼层
回复 3# happy886rr


    命令行版提示找不到词典,在程序目录或者工作目录下都不行,词典的名称没有更改
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:46 , Processed in 0.017754 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表