热度 28
2010-12-30 12:16
4009 次阅读|
13 个评论
前言 如 topic 所示, 这是一个很传统的知识点. 当我们的项目, 需要将 gb码转化为 Unicode 码时, 我们进行大量文章检索后, 郁闷发现, 很难找到现成的转换表文件为我们所用. 在发现一份被定义的转化表头文件后, Allen 如获珍宝, 立即将该转换表数组, 做成一个转换文件, 以节省同行进行同议题探讨的时间. 工作步骤 1. 获取gb2unicode 头文件: 因为匆忙工作, 未能记录下从哪位同仁的blog中获得, 该 gb2unicode 的码表头文件.对此这里表歉意了. 该头文件定义如下: //#typedef unsigned short int uint16; #define MAX_UNI_INDEX 6768 //const uint16 GB_TO_UNI = const unsigned short int GB_TO_UNI = { {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 ; memset(tmp, 0, sizeof(tmp)); for(int i=0; i tmp = GB_TO_UNI 8; tmp = (BYTE)GB_TO_UNI ; tmp = GB_TO_UNI 8; tmp = (BYTE)GB_TO_UNI ; file.Write(tmp, sizeof(tmp)); } file.Close(); CString sMsg = "Build " + strFileName + " successed!"; AfxMessageBox(sMsg); } 3. 使用二分法基于GB码之索引查找Unicode 码 void CBuild_GBtoUnicode_fileDlg::OnButtonTrax() { BYTE sTemp ; 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 127) { flag = TRUE; } } else if(len == 2) { index = (sTemp 8) + sTemp ; if( (index0xb0a1) || (index0xf7fe) ) { 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 ); m_editSrc.SetWindowText(sSource); sDirection.Format("0x00 0x%x", sTemp ); m_editDrt.SetWindowText(sDirection); } // gb char with lookup table of bin file else if(len == 2) { sSource.Format("0x%x 0x%x", sTemp , sTemp ); 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 ; while(low { mid = (low+high)/2; file.Seek((mid2)+2, CFile::begin); file.Read((char*)tmp, 2); gbcode_mid = (tmp 8) + tmp ; if( index gbcode_mid ) high--; else if( index gbcode_mid ) low++; else break; } if(lowhigh) { AfxMessageBox("Cannot find gb char in current gb2unicode table!"); return; } // result file.Seek( (mid2), CFile::begin ); file.Read((char*)tmp, 2); sDirection.Format("0x%x 0x%x", tmp , tmp ); m_editDrt.SetWindowText(sDirection); file.Close(); } } 验证 使用一个测试工具, 我们验证了头尾以及中间若干GB码. 其结果与头文件之码表数组均一一匹配. 总结 在GB to UNICODE 这个传统的topic 中, 我们借助网络查询, 在接近1个工作日的时间内, 并没有找到一个合适的转换文件. 故基于一个转化数组的帮助下, 我们制作了该转换文件, 一般可用于保存在 FLASH 中, 供同行们使用 MCU 来检索对应的 UNICODE 码. 同时, 要指出因为二分法的使用, 查表的速度应符合普通应用. 我们记录工作于此 blog, 我们希望能有助于同行进行类似的工作, 不再浪费宝贵的工程时间于此传统议题上. Allen 作于深圳福田 2010.12.30