libarryOut.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:7k
源码类别:

输入法编程

开发平台:

Visual C++

  1. // loadmylib.cpp: implementation of the loadmylib class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "libarryOut.h"
  6. #include "stdio.h"
  7. //////////////////////////////////////////////////////////////////////
  8. // Construction/Destruction
  9. //////////////////////////////////////////////////////////////////////
  10. libarryOut::libarryOut()
  11. {
  12. MainCode=NULL;
  13. CodeNum=0;
  14. CodeLong=0;
  15. }
  16. libarryOut::~libarryOut()
  17. {
  18. }
  19. //输出单个字的主要编码
  20. //库必须以第一个汉字为序以便进行二分法比较
  21. //开头的四个字节为库的编码个数CodeNum,后路回车
  22. libarryOut::OutsourceOne(char  * outLibName)
  23. {
  24.   char ss1[2000],ss[2000],cc[1000],testss[1000],*p=NULL;
  25.   char temcodess[1000];
  26.   unsigned long recodenum=0,codenum=0;
  27.   unsigned long tt,i,klen;
  28.   FILE  * outfp;
  29.   char *LMaincode;
  30.   
  31.   unsigned short int *intp1;
  32.   char intpss1[6];
  33.   intp1=(unsigned short*)intpss1;
  34.    outfp=fopen(outLibName, "wb");    /*打开目标文件*/ 
  35.    if(outfp==NULL){
  36.       MessageBox(0,"Outsource函数打开文件失败","错误",0);
  37.   return 0;
  38. }
  39.   tt=*IndexNum;
  40.   LMaincode=new char[0xffff*10+100];
  41.   for(i=0;i<65535;i++)
  42.   {
  43.   LMaincode[i*10]=0;
  44.   }
  45.   for(i=0;i<tt;i++)
  46.   {
  47.   p=&CLIB_EnCh[LIBIndex[i]];
  48.   strcpy(ss,p);
  49.   if(!((ss[0]>='A'&& ss[0]<='Z')))
  50.   MessageBox(0,p,"错误",0);
  51.   p+=strlen(ss)+1;
  52.   strcpy(cc,p);
  53.   //重码必需分开
  54.    p = strtok(cc, ";"); 
  55.    while (p!=NULL)   
  56.    {
  57.    sprintf(testss,"%s",p);
  58.    klen=strlen(ss);
  59.    if(strlen(testss)==2 && (klen>=2 && klen <= 4))
  60.    {// klen取大于或等于2是为了在两个字时组成4个长的编码,1个就不行了,小于4是为了去除拼音
  61. // testss==2是为了只取单个字的编码
  62.    if(klen==2)
  63.    sprintf(temcodess,"%s %s  xdxa",p,ss1);
  64.    if(klen==3)
  65.    sprintf(temcodess,"%s %s xdxa",p,ss1);
  66.    if(klen==4)
  67.    sprintf(temcodess,"%s %sxdxa",p,ss1);
  68.    //以上是为了统一输出宽度
  69.    intpss1[1]=*p;
  70.    intpss1[0]=*(p+1);
  71.    if(LMaincode[*intp1*10]==0)//只输出第一次出现的字
  72.    {
  73.    strcpy(&LMaincode[*intp1*10],temcodess);
  74.    codenum++;
  75.    }
  76.    }
  77.    p = strtok(NULL, ";"); 
  78.    }
  79.   }
  80.    fwrite(&codenum,sizeof(unsigned long),1,outfp);
  81.    fprintf(outfp,"xdxa");
  82.    sprintf(temcodess,"%ld",codenum);
  83.    MessageBox(0,temcodess,"生成词个数",0);
  84.   for(i=0;i<0xffff;i++)
  85.   {
  86.    if(LMaincode[i*10]!=0)
  87.    {
  88.    fprintf(outfp,"%s",&LMaincode[i*10]);
  89.    }
  90.   }
  91.   delete[]LMaincode;
  92.   fclose(outfp);
  93.   return 0;
  94. }
  95. //反编码输出全部的汉字编码
  96. libarryOut::Outsource(char  * outLibName)
  97. {
  98.   char ss[5000],cc[5000],*p=NULL;
  99.   unsigned long tt,i;
  100.   FILE  * outfp;
  101.   outfp=fopen(outLibName, "wb");    /*打开目标文件只读*/ 
  102.    if(outfp==NULL){
  103.       MessageBox(0,"Outsource函数打开文件失败","错误",0);
  104.   return 0;
  105. }
  106.   tt=*IndexNum;
  107.   for(i=0;i<tt;i++){
  108.   p=&CLIB_EnCh[LIBIndex[i]];
  109.   strcpy(ss,p);
  110.   p+=strlen(ss)+1;//把代码转换成字符串
  111.   strcpy(cc,p);
  112.   //重码必需分开
  113.    p = strtok(cc, ";"); 
  114.    while (p!=NULL)   
  115.    {
  116.        //MessageBox(0,p,"错误",0);
  117.    fprintf(outfp,"%s %sxdxa",ss,p);
  118.    p = strtok(NULL, ";"); 
  119.    }
  120. //   fprintf(outfp,"%s %sxdxa",ss,p);
  121.   }
  122.   fclose(outfp);
  123.   return 0;
  124. }
  125. //CodeNum,CodeLong ,MainCode为全局变量,可提高多次转换码时的速度
  126. long libarryOut::ChissToCode(char *MainCodeLibName,char *chiss,char *resultss)
  127. {
  128. FILE  *infp;
  129. int ret,i;
  130. char temss[100];
  131.     if(MainCode==NULL)
  132. {
  133. CodeLong=9;//以库文件中实际的长度为准
  134. /////////////////////////////////////////////////////////////////
  135. //主字库装入
  136. infp=fopen(MainCodeLibName, "rb");    /*打开文字文件只读*/ 
  137. if(infp==NULL){
  138.   MessageBox(0,MainCodeLibName,"ChissToCode函数打开文件失败",0);
  139.   return 0;
  140. }
  141. //取代码数
  142. ret=fread(&CodeNum,4,1,infp);
  143. if(ret==-1)
  144. {
  145.   MessageBox(0,"ChissToCode函数读取词库大小失败","错误",0);
  146.   return 0;
  147. }
  148. MainCode=new char[CodeNum*10+10000];
  149. ret=fread(temss,2,1,infp); //再跳过2个字节
  150. ret=fread(MainCode,CodeNum*CodeLong,1,infp); 
  151. MainCode[0];
  152. if(ret==-1)
  153. {
  154.   MessageBox(0,"ChissToCode函数读取主词库失败","错误",0);
  155.   return 0;
  156. }
  157. //主字库装入完毕
  158. /////////////////////////////////////////////////////////////////
  159. }
  160. if(chiss!=NULL)
  161. {
  162. for(i=0;i<10;i++)
  163. temss[i]=chiss[i];
  164. TranslatewbCode(MainCode,CodeNum,CodeLong,chiss,resultss);
  165. }
  166.     //MessageBox(0,resultss,"转换结果",0);
  167. //&maincode[codenum*CodeLong-9];
  168. return 0;
  169. }
  170. //把汉字串转换成五笔编码格式
  171. //maincode为加载库,codenum为主编码的个数,CodeLong为单个编码的长度
  172. int libarryOut::TranslatewbCode(char *maincode,unsigned long codenum,unsigned long CodeLong,char *chiss,char* resultss)
  173. {
  174. char temresultss[10];
  175. unsigned long len,i;
  176. char ss[100];
  177. len=strlen(chiss);
  178. if(len%2!=0)
  179. return 1;
  180. if( len==2)
  181. MainFindtoCode(maincode,codenum,CodeLong,chiss,resultss);
  182. if( len==4)
  183. {
  184. MainFindtoCode(maincode,codenum,CodeLong,chiss,temresultss);
  185. resultss[0]=temresultss[0];
  186. resultss[1]=temresultss[1];
  187. resultss[2]=temresultss[4+0];
  188. resultss[3]=temresultss[4+1];
  189. resultss[4]=0;
  190. }
  191. if( len==6)
  192. {
  193. MainFindtoCode(maincode,codenum,CodeLong,chiss,temresultss);
  194. resultss[0]=temresultss[0];
  195. resultss[1]=temresultss[4];
  196. resultss[2]=temresultss[8];
  197. resultss[3]=temresultss[8+1];
  198. resultss[4]=0;
  199. }
  200. if( len>6)
  201. {
  202. for(i=0;i<6;i++)
  203. ss[i]=chiss[i];
  204. ss[i]=0;
  205. MainFindtoCode(maincode,codenum,CodeLong,ss,temresultss);
  206. resultss[0]=temresultss[0];
  207. resultss[1]=temresultss[4];
  208. resultss[2]=temresultss[8];
  209. ss[0]=chiss[len-2];
  210. ss[1]=chiss[len-2+1];
  211. ss[2]=0;
  212. MainFindtoCode(maincode,codenum,CodeLong,ss,temresultss);
  213. resultss[3]=temresultss[0];
  214. resultss[4]=0;
  215. }
  216. return 0;
  217. }
  218. //在指定的库中转换汉字串,
  219. //maincode为加载库,格式为先为汉字,后为编码。
  220. //codenum为主编码的个数,CodeLong为单个编码的长度
  221. //库必须以第一个汉字为序以便进行二分法比较
  222. int libarryOut::MainFindtoCode(char *maincode,unsigned long codenum,unsigned long CodeLong,char *chiss,char* resultss)
  223. {
  224. unsigned short int *intp2,*intp1;
  225. long high,low,mid,i,len;
  226. char intpss1[6],intpss2[6],temss[1000],temss1[10];
  227. char temresultss[10];
  228. int t;
  229. temss[0]=0;
  230. resultss[0]=0;
  231. intp1=(unsigned short*)intpss1;
  232. intp2=(unsigned short*)intpss2;
  233. len=strlen(chiss);
  234. t=len/2;
  235. for(i=0;i<t;i++)
  236. {
  237. high=codenum-1;
  238. low=0;
  239. intpss1[1]=chiss[i*2];
  240. intpss1[0]=chiss[i*2+1];
  241. while(high>=low)
  242. {
  243. mid=low+(high-low)/2;
  244. //&maincode[mid*CodeLong];
  245. intpss2[1]=maincode[mid*CodeLong];
  246. intpss2[0]=maincode[mid*CodeLong+1];
  247. if(*intp1==*intp2)//由于字符型转换成了整型所有可以直接比较
  248. {
  249. temresultss[0]=maincode[mid*CodeLong+3];
  250. temresultss[1]=maincode[mid*CodeLong+3+1];
  251. temresultss[2]=maincode[mid*CodeLong+3+2];
  252. temresultss[3]=maincode[mid*CodeLong+3+3];
  253. temresultss[4]=0;
  254. strcat(resultss,temresultss);
  255. break;
  256. }
  257. if(*intp1>*intp2)
  258. low=mid+1;
  259. else
  260. high=mid-1;
  261. }////while
  262. if(high<low)
  263. {
  264. temss1[0]=chiss[i*2];
  265. temss1[1]=chiss[i*2+1];
  266. temss1[2]=0;
  267. if(strlen(temss)<990)
  268. strcat(temss,temss1);
  269. else
  270. {
  271. MessageBox(0,"有太多的字未找到,请重新组织","主字库中没有要找的字",0);
  272. return 1;
  273. }
  274. }
  275. }////for
  276. // if(temss[0]!=0)
  277. // MessageBox(0,temss,"主字库中没有要找的字",0);
  278. return 0;
  279. }