MULTCODE.CPP
上传用户:zhang8947
上传日期:2007-01-08
资源大小:1910k
文件大小:6k
源码类别:

多国语言处理

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include <windowsx.h>
  3. #include "cspublic.h"
  4. #include "multcode.h"
  5. CJudgeCode OJudgeCode( JUDGE_LIB_NAME ) ;
  6. //自动判断,需要怎么处理内码
  7. //返回0为国标码,1为BIG5码,2,3,4为其它缺省内码
  8. int JudgeCode( LPSTR lpsStr , int nNum ) //判断为何种内码
  9. {
  10. int nResult ;
  11. if( GetRecGbBig5() ) //需要自动识别GB与BIG5内码
  12. //判断是何种内码
  13. nResult =OJudgeCode.JudgeGBorBig5( lpsStr , nNum ) ;
  14. else //不需要自动识别内码
  15. {
  16. nResult =GetOutputCode() ; //得到缺省输出内码
  17. if( nResult==1 ) //BIG5
  18. ChangeBig5ToGb( lpsStr , nNum ) ; //转换内码
  19. }
  20. if( GetRecHz() ) //需要自动识别HZ码
  21. OJudgeCode.JudgeHZ( lpsStr , nNum ) ;
  22. return nResult ;
  23. }
  24. //--------------------------------------------------------------------------------------------//
  25. //自动判断是何种内码
  26. CJudgeCode::CJudgeCode( char * psFileName ):
  27.  CFile( psFileName , CFile::modeRead )
  28. {
  29. DWORD dwFileLen =GetLength() ; //得到文件长度
  30. if( dwFileLen % 4  ) //不能被4整除
  31. {
  32. ::MessageBox( 0 , "The length of the file is wrong!" , 0 , MB_OK ) ;
  33. return ;
  34. }
  35. m_nItemNum =(int)(dwFileLen / 4) ; //表中项数
  36. //分配内存
  37. m_lpsList =(char huge*)GlobalAllocPtr( GMEM_FIXED ,
  38. dwFileLen ) ;
  39. if( !m_lpsList )
  40. {
  41. ::MessageBox( 0 , "GlobalAllocPtr error" , 0 , MB_OK ) ;
  42. return ;
  43. }
  44. //读出词组表
  45. ReadHuge( m_lpsList , dwFileLen ) ;
  46. Close() ;
  47. }  
  48. CJudgeCode::~CJudgeCode( void )
  49. {
  50. if( m_lpsList )
  51. GlobalFreePtr( m_lpsList ) ;
  52. }
  53. //自动判断字符串是GB码还是BIG5码
  54. int CJudgeCode::JudgeGBorBig5( LPSTR lpsStr , int nNum )
  55. {
  56. //判断其是否为GB码
  57. if( IsGB( lpsStr , nNum ) )
  58. return( 0 ) ; //为GB码
  59. //得到当前缺省内码
  60. int nResult =GetOutputCode() ;
  61. if( nResult==1 ) //是BIG5
  62. {
  63. ChangeBig5ToGb( lpsStr , nNum ) ; //将其转换为GB码
  64. return( 1 ) ; //是BIG5
  65. }
  66. //输入字符串不是GB码,假设其为BIG5,将其转换为GB码
  67. LPSTR lpsString =(LPSTR)GlobalAllocPtr( GMEM_FIXED ,
  68. nNum ) ;
  69. if( !lpsString )
  70. {
  71. ::MessageBox( 0 , "GlobalAllocPtr error,in JudgeCode" , 0 , MB_OK ) ;
  72. return -1 ;
  73. }
  74. _fstrncpy( lpsString , lpsStr , nNum ) ; //复制
  75. ChangeBig5ToGb( lpsString , nNum ) ;
  76. //判断转换结果是否是GB码
  77. if( IsGB( lpsString , nNum ) ) //输入串是BIG5
  78. {
  79. _fstrncpy( lpsStr , lpsString , nNum ) ; //复制
  80. GlobalFreePtr( lpsString ) ;
  81. return( 1 ) ;
  82. }
  83. GlobalFreePtr( lpsString ) ;
  84. //输入串即不是GB码、也不是BIG5码,以缺省内码GB码为准
  85. return( nResult ) ;
  86. }
  87. //判断字符串是否是GB码
  88. int CJudgeCode::IsGB( LPSTR lpsStr , int nNum )
  89. {
  90.     int     nLinePoint ; //字符指针
  91.     char    sWordBuff[4] ;
  92.     int n ;
  93.     
  94.     nLinePoint  =0 ; //设置字符指针
  95.     //得到第一个字
  96. l100: while( 1 )
  97. {
  98. n =GetZi( lpsStr , nNum , (LPINT)&nLinePoint , (LPSTR)sWordBuff ) ;
  99. if( !n )  //到字符串尾
  100. return 0 ;
  101. if( n == 2 ) //连续二个汉字
  102. break ;
  103. }
  104. do
  105. {
  106. //得到第二个字
  107.         n =GetZi( lpsStr , nNum , (LPINT)&nLinePoint , 
  108.          (LPSTR)(sWordBuff+2) ) ;
  109.         if( !n ) //到字符串尾
  110.          return 0 ;
  111.         
  112.         //判断该两个字是否能够组成一个词
  113.         if( IsWord( (LPSTR)sWordBuff ) )       //是一个词
  114.          return 1 ; //是GB码
  115.     
  116.      if( n == 2 ) //下面还有一字
  117.      {
  118.          //保存第二个字,即丢弃第一个字,以第二个字为第一个字
  119.          sWordBuff[0] =sWordBuff[2] ;
  120.          sWordBuff[1] =sWordBuff[3] ;
  121.         }
  122.         else //下面已经没有字,要找第一个汉字
  123.          goto l100 ;
  124. } while( 1 ) ;        
  125. }
  126. //从字符串中得到一个汉字
  127. int CJudgeCode::GetZi( LPSTR lpsLine , int nNum , 
  128. LPINT lpnLinePoint , LPSTR lpsZi )
  129. {
  130. for( int i=*lpnLinePoint ; i < nNum-1 ; i++ )
  131. {
  132. if( lpsLine[i]&0x80 ) //遇到一个汉字
  133. {
  134. //记录该汉字
  135.      lpsZi[0]  =lpsLine[i++] ;
  136.      lpsZi[1]  =lpsLine[i++] ;
  137. *lpnLinePoint =i ; //记录指针    
  138. //判断下一个是否也是汉字
  139. if( i < nNum - 1 ) //还有可能组成汉字    
  140. {
  141. if( lpsLine[i]&0x80 ) //也是汉字
  142. return 2 ; //连续两个都是汉字
  143. }
  144. return 1 ; //下一个不是汉字
  145. }
  146. }
  147. return 0 ; //找不到汉字
  148. }
  149. //判断该几个字是否能够组成一个词
  150. int CJudgeCode::IsWord( LPSTR lpsWordBuff )
  151. {
  152. LONG nFirst=0 ; //表头
  153. LONG nLast=m_nItemNum-1 ; //表尾
  154. LONG nMiddle ; //表中
  155. int n ;
  156. while( nFirst <= nLast )
  157. {
  158. nMiddle =( nFirst+nLast )/2 ; //二分
  159. n =_fstrncmp( m_lpsList+nMiddle*4 , lpsWordBuff , 4 ) ;
  160. if( !n ) //相等
  161. return 1 ;
  162. if( n < 0 )
  163. nFirst =nMiddle+1 ;
  164. else
  165. nLast =nMiddle-1 ;
  166. }
  167. return 0 ;
  168. }
  169. //判断是否存在HZ码
  170. void CJudgeCode::JudgeHZ( LPSTR lpsStr , int nNum )
  171. {
  172. int nSub =0 ;
  173. for( int i=0 ; i<nNum-1 ; )
  174. {
  175. //寻找头
  176. if( lpsStr[i+nSub] == '~' && lpsStr[i+nSub+1] == '{' ) //是头
  177. {
  178. nNum -=2 ; //长度-2
  179. nSub +=2 ;
  180. //将头后字符串前移
  181. while( i<nNum )
  182. {
  183. if( i == nNum-1 ) //最后一个字符
  184. {
  185. lpsStr[i] =lpsStr[i+nSub] | 128 ;
  186. break ;
  187. }
  188. if( lpsStr[i+nSub] == '~' && lpsStr[i+nSub+1] == '}' ) //是尾
  189. {
  190. nNum -=2 ; //字符串长度-2
  191. nSub +=2 ;
  192. break ; //跳出这个循环
  193. }
  194.  
  195. switch( lpsStr[i+nSub] )
  196. {
  197. case '#':  //将其后的英文字符改成中文字符
  198. lpsStr[i++] =0xa3 ; //第3区为中文字符
  199. lpsStr[i] =lpsStr[i+nSub] | 128 ;
  200. break ;
  201. case '