<前言>
如 topic 所示, 这是一个很传统的知识点. 当我们的项目, 需要将 gb码转化为 Unicode 码时, 我们进行大量文章检索后, 郁闷发现, 很难找到现成的转换表文件为我们所用. 在发现一份被定义的转化表头文件后, Allen 如获珍宝, 立即将该转换表数组, 做成一个转换文件, 以节省同行进行同议题探讨的时间.
<工作步骤>
1. 获取gb2unicode 头文件:
因为匆忙工作, 未能记录下从哪位同仁的blog中获得, 该 gb2unicode 的码表头文件.对此这里表歉意了. 该头文件定义如下:
//#typedef unsigned short int uint16;
#define MAX_UNI_INDEX 6768
//const uint16 GB_TO_UNI[MAX_UNI_INDEX][2]=
const unsigned short int GB_TO_UNI[MAX_UNI_INDEX][2]=
{
{0x554A,0xB0A1},//GB2312:啊
{0x963F,0xB0A2},//GB2312:阿
{0x57C3,0xB0A3},//GB2312:埃
{0x6328,0xB0A4},//GB2312:挨
// ...
{0x9F3D,0xF7FC},//GB2312:鼽
{0x9F3E,0xF7FD},//GB2312:鼾
{0x9F44,0xF7FE}//GB2312:齄
};
2. 生成 gb2unicode.bin 文件:
void CBuild_GBtoUnicode_fileDlg::OnButtonBuild()
{
CString strPath = GetDeviceFullPath();
CString strFileName = strPath + "gb2unicode.bin";
// build file
CString sTemp;
CFile file( strFileName, CFile::modeCreate | CFile::modeWrite );
BYTE tmp[4];
memset(tmp, 0, sizeof(tmp));
for(int i=0; i tmp[0] = GB_TO_UNI[0]>>8;
tmp[1] = (BYTE)GB_TO_UNI[0];
tmp[2] = GB_TO_UNI[1]>>8;
tmp[3] = (BYTE)GB_TO_UNI[1];
file.Write(tmp, sizeof(tmp));
}
file.Close();
CString sMsg = "Build " + strFileName + " successed!";
AfxMessageBox(sMsg);
}
3. 使用二分法基于GB码之索引查找Unicode 码
void CBuild_GBtoUnicode_fileDlg::OnButtonTrax()
{
BYTE sTemp[4];
memset(sTemp, 0, sizeof(sTemp));
m_editChar.GetWindowText((char*)sTemp, sizeof((char*)sTemp));
UINT len = strlen((char*)sTemp);
UINT index = 0;
BOOL flag = FALSE;
if(len == 1) {
if(sTemp[0] > 127) { flag = TRUE; }
}
else if(len == 2) {
index = (sTemp[0]<<8) + sTemp[1];
if( (index<0xb0a1) || (index>0xf7fe) ) { flag = TRUE; }
}
else {
flag = TRUE;
}
if(flag == TRUE) {
AfxMessageBox("Please input the correct Chinese char or ascII char!");
return;
}
// do trax
CString sSource, sDirection;
// arcII char
if(len == 1) {
sSource.Format("0x%x", sTemp[0]);
m_editSrc.SetWindowText(sSource);
sDirection.Format("0x00 0x%x", sTemp[0]);
m_editDrt.SetWindowText(sDirection);
}
// gb char with lookup table of bin file
else if(len == 2) {
sSource.Format("0x%x 0x%x", sTemp[0], sTemp[1]);
m_editSrc.SetWindowText(sSource);
// find unicode code based on gb code
CFile file;
CString strPath = GetDeviceFullPath();
CString sBinFilename = strPath + "gb2unicode.bin";
if(!file.Open(sBinFilename, CFile::modeRead)) {
AfxMessageBox("File can NOT be openned!");
return;
}
// half mothed
int low,high,mid;
low = 0; high = MAX_UNI_INDEX;
UINT gbcode_mid = 0;
BYTE tmp[2];
while(low {
mid = (low+high)/2;
file.Seek((mid<<2)+2, CFile::begin);
file.Read((char*)tmp, 2);
gbcode_mid = (tmp[0]<<8) + tmp[1];
if( index < gbcode_mid ) high--;
else if( index > gbcode_mid ) low++;
else break;
}
if(low>high) {
AfxMessageBox("Cannot find gb char in current gb2unicode table!");
return;
}
// result
file.Seek( (mid<<2), CFile::begin );
file.Read((char*)tmp, 2);
sDirection.Format("0x%x 0x%x", tmp[0], tmp[1]);
m_editDrt.SetWindowText(sDirection);
file.Close();
}
}
<验证>
使用一个测试工具, 我们验证了头尾以及中间若干GB码. 其结果与头文件之码表数组均一一匹配.
<总结>
在GB to UNICODE 这个传统的topic 中, 我们借助网络查询, 在接近1个工作日的时间内, 并没有找到一个合适的转换文件.
故基于一个转化数组的帮助下, 我们制作了该转换文件, 一般可用于保存在 FLASH 中, 供同行们使用 MCU 来检索对应的 UNICODE 码. 同时, 要指出因为二分法的使用, 查表的速度应符合普通应用.
我们记录工作于此 blog, 我们希望能有助于同行进行类似的工作, 不再浪费宝贵的工程时间于此传统议题上.
Allen 作于深圳福田
2010.12.30
用户1085119 2011-8-8 09:07
用户1322273 2011-1-5 21:51
用户1291225 2011-1-5 08:42
用户1371612 2011-1-4 09:42
用户1101468 2011-1-3 22:24
allen_zhan_752827529 2011-1-3 11:49
用户1190859 2011-1-3 11:36
用户1409907 2011-1-3 11:21
用户1379464 2011-1-3 09:14
good material and wish God bless you.
f737_486061703 2010-12-31 09:09