标题: 跨平台的命令行字典外壳 dic.exe [打印本页]
作者: happy886rr 时间: 2017-5-31 02:47 标题: 跨平台的命令行字典外壳 dic.exe
下载:城通网盘https://page37.ctfile.com/fs/14274637-204821002
跨平台源码:- /*
- 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;
- }
复制代码
补充:附带几个移植到手机上的第三方,手机上的控制台一样精彩。包括: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://bbs.bathome.net/) |
Powered by Discuz! 7.2 |