嵌入式系统汉字输入
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/bbs/viewthread.php?tid=8868&extra=page%3D2
1.简单知识
中文输入发我不多说,大家都用过,目前嵌入式系统中比较典型的中文输入法有诺基亚的T9 、摩托罗拉的 i T A P 、爱立信的字能等,这些输入法的输入设备一般是数字键0 ~ 9和一些功能键组成。
除了支持中文的拼音和笔画外还支持诸如日文、韩文等其他国家的语言。
中文输入法可分为拼音输入和笔画输入。
一般情况下拼音输入法相对笔画输入法,重码率要高,但简单易用,(再加个模式识别进行手写输入就更高级了,呵呵),我这里也是拼音输入,由于空间有效,不支持联想功能.
2. 硬软件
硬件用的NXP的2138,LCD是台湾雄铎科技的,240*160,软件用的zlg的模板,uc2.52版,按键布局与手机一样,如"2"键为abc,"3"为def,等等
3.前期准备
3.1网上有许多的资料,给出了键盘数字组合对应的拼音组合和汉字组合,我也利用这个,如{"2","a",(char *)PY_mb_a},
{"24","ai",(char *)PY_mb_ai},
{"26","an",(char *)PY_mb_an},
{"26","ao",(char *)PY_mb_ao},
{"22","ba",(char *)PY_mb_ba},
{"24","bi",(char *)PY_mb_bi},
const char PY_mb_a[] ={"阿啊"};
const char PY_mb_ai[] ={"矮蔼艾爱隘碍霭"};
但有个问题,这个网上流传的拼音-汉字组合中汉字非常少,对于输入是远远不够的,比如说"汶川"的汶就没有,而且没有多音字,例如"还"的拼音属于"huan",你打"还"就没有,这对于输入是不可以接收的,下面我讲一下我的解决方法.
3.2寻找所有汉字的拼音,这个如果打开字典一个一个的输,恐怕没有一个月是干不成了,庆幸的是有人替我们做好了,在万能五笔输入法中有一个拼音记录文件,几乎包括了所有的汉
字,拿来所用
py_gb.rar (264.6 KB)
这个文件中,有许多词组,是我们不需要的,需要剔掉,但手工的方式工作量太大,这里我们发
挥计算机比较傻的优势来做这件事,用到一些VC的基本知识,相信大家都有这个能力
CStdioFile read_file,read_new_file;
CStdioFile write_file;
CString my_str,temp_str,tf="";
read_file.Open( "py_gb.txt", CFile::modeRead,NULL ) ;
write_file.Open( "new_py_gb.txt", CFile::modeCreate | CFile::modeWrite,NULL ) ;
while (read_file.ReadString(my_str))
{
int i = my_str.Find(" ");
if ((my_str.GetLength() - i) > 3)
{
/* 是词组 */
continue;
}
else
{
/* 保存到文件 */
write_file.WriteString(my_str);
write_file.WriteString("\n");
}
}
read_file.Close();
write_file.Close();
原理也非常简单,如果是词组,汉字的个数肯定大于1,在vc中,一个ASCII占一个字节,一个
汉字占两个字节,整理后的文件如下
new_py_gb.rar (65.71 KB)
3.3
在文件new_py_gb.txt中,列出了每个字的拼音,如
a 啊
a 阿
a 呵
a 吖
a 嗄
a 腌
a 锕
a 錒
aes 厑
ai 爱
ai 矮
ai 挨
ai 哎
ai 碍
ai 癌
ai 艾
ai 唉
ai 哀
ai 蔼
到这里又产生一个问题,必须将所有的同音汉字组合在一起,例如拼音为a的,应该这样
a啊阿呵吖嗄腌锕錒
vc程序如下:
read_file.Open( "py_file.c", CFile::modeRead,NULL ) ;
read_new_file.Open("new_py_gb.txt", CFile::modeRead,NULL);
write_file.Open( "zhenli.txt", CFile::modeCreate | CFile::modeWrite,NULL ) ;
while (read_file.ReadString(my_str))
{
int i = my_str.Find(",");
int j = my_str.Find(",",i);
temp_str = my_str.Mid(i + 2, j - 3);
CString save_str = temp_str;
while (read_new_file.ReadString(tf))
{
int ll = tf.Find(" ");
if (tf.Left(ll) == temp_str)
{
save_str += tf.Right(2);
}
}
write_file.WriteString(save_str );
write_file.WriteString("\n");
read_new_file.SeekToBegin();
}
原理就是把所有拼音相同的字组合在一起,这个过程比较慢,需要耐心等待,不要以为程序死
掉了,呵呵,生成的zhenli.txt文件如下:
a啊阿呵吖嗄腌锕錒
e饿哦额鹅蛾扼俄讹阿遏峨娥恶厄鄂锇谔垩锷阏萼苊轭婀莪鳄颚腭愕呃噩鹗屙亚亜亞伪佮侉偔偽僞僫匎匼卾吪呝咢咹哑唖啈啊啐啞噁囐囮垭埡堊堨堮妸妿姶娾娿媕屵岋峉峩崿庵廅悪惡戹搕搤搹擜曷枙椏櫮欸歞歹歺洝涐湂玀珴琧痷皒睋砈砐砨砵硆硪磀礘胺蒍蕚蘁蚅蝁覨訛詻誐諤譌讍豟軛軶輵迗遌遻邑鈋鋨鍔鑩閜閼阨阸隘頞頟額顎餓餩騀鬲魤魥鰐鰪鱷鴳鵈鵝
鵞鶚齃齶齾
…………3.4又产生一个新问题,里面的字太多了,许多生僻的字连GB2312编码中都没有,这些字对于应用是没有用的,必须剔除,于是:
找到GB2312编码的所有汉字
啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘
鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱
袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋
靶把耙坝霸罢爸白柏百摆佰败拜稗斑
班搬扳般颁板版扮拌伴瓣半办绊邦帮
梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥
GB2312.rar (11.01 KB)
为了方便,做进一步的整理,将一个段位的所有字放到一行中:
啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦
帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥
薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖
憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳
read_file.Open( "gb2312.txt", CFile::modeRead,NULL ) ;
write_file.Open( "gb2312_new.txt", CFile::modeCreate | CFile::modeWrite,NULL ) ;
int i = 0;
while (read_file.ReadString(my_str))
{
if (my_str == "")
{
continue;
}
i++;
tf += my_str;
if (i == 6)
{
write_file.WriteString(tf);
write_file.WriteString("\n");
i = 0;
tf = "";
}
}
gb2312_new.rar (471 Bytes)
3.5
对比GB2312中有的汉字,依次查找zhenli.txt中的每个汉字是否是有效的,在这里我做了个假设,如果一个拼音下的某个汉字不存在,z则其后的汉字也不存在,即
e饿哦额鹅蛾扼俄讹阿遏峨娥恶厄鄂锇谔垩锷阏萼苊轭婀莪鳄颚腭愕呃噩鹗屙亚亜亞伪佮侉偔偽僞僫匎匼卾吪呝咢咹哑唖啈啊啐啞噁囐囮垭埡
中,“亜”不存在,则其后的字都剔除,这样是合理的,以为即使某个字存在,他的拼音现在
也不用了
read_file.Open( "gb2312_new.txt", CFile::modeRead,NULL ) ;
read_new_file.Open("zhenli.txt", CFile::modeRead,NULL);
write_file.Open( "valid_chinese.txt", CFile::modeCreate | CFile::modeWrite,NULL ) ;
CString gb2312_buffer="";
while (read_file.ReadString(my_str))
{
gb2312_buffer+=my_str;
}
while (read_new_file.ReadString(my_str))
{
int i = 0;
char * p_str = my_str.GetBuffer(0);
CString used_in_str="";
/* 去掉行首的拼音*/
while (!(*p_str & 0x80))
{
p_str++;
i++;
}
used_in_str = my_str.Left(i);
temp_str = my_str.Right(my_str.GetLength()-i); for (i = 0;i < temp_str.GetLength();i++,i++)
{
tf = temp_str.Mid(i,2);
/* 在GB2312的文件中查找是否存在*/ if (-1 == (gb2312_buffer.Find(tf)))
{
/* 没发现此字,则认为后续的字都不存在*/ write_file.WriteString(used_in_str);
write_file.WriteString("\n");
break;
}
used_in_str+=tf;
}
}
生成的文件为
a啊阿呵吖嗄腌锕
e饿哦额鹅蛾扼俄讹阿遏峨娥恶厄鄂锇谔垩锷阏萼苊轭婀莪鳄颚腭愕呃噩鹗屙
m呒
n嗯
o哦喔噢
…………
附件
valid_chinese.rar(13.49 KB)
2008-5-25 10:28, 下载次数: 83
3.6
将valid_chines.txt中的格式向py_file.txt中的格式靠拢
read_file.Open( "py_file.txt", CFile::modeReadWrite,NULL ) ;
read_new_file.Open("valid_chinese.txt", CFile::modeRead,NULL);
write_file.Open("new_py_file.txt", CFile::modeWrite | CFile::modeCreate,NULL);
while (read_new_file.ReadString(my_str))
{
int i = 0;
char * p_str = my_str.GetBuffer(0);
CString used_in_str="";
/* 去掉行首的拼音 */
while (!(*p_str & 0x80))
{
p_str++;
i++;
}
used_in_str = my_str.Right(my_str.GetLength() - i);
/* 将第一个字去py_file.txt中寻找,找到后将本字符串替换到文件中 */
tf = used_in_str.Left(2);
CString ss;
read_file.SeekToBegin();
while (read_file.ReadString(ss))
{
if (ss.Find(tf) != -1)
{
/* 找到第一个"位置 */
CString new_ss = ss.Left(ss.Find("\"") + 1);
new_ss += used_in_str;
new_ss += "\"};\n";
write_file.WriteString(new_ss);
break;
}
}
}
但发现有一个新问题,依照上面的算法,如果多音字在行首,则会出现下面的问题:
比如:
在valid_chinese.txt中
hai还海害咳氦孩骇咳骸亥嗨醢胲侅咍咴嗐嚡塰拸欬烸猲絯還郂酼閡阂頦颏餀饚駭駴liao了料撩聊撂疗廖燎辽僚寥镣潦钌蓼尥寮缭獠鹩嘹佬僇劳勞嫽尞尦屪嵺嶚嶛廫憀憭摎敹暸樛漻炓爎爒璙療瞭窷竂簝繚膋膫蟉蟟蟧豂賿蹘蹽轑遼鄝釕鏐鐐镠镽飂飉髎鷯chang长唱常场厂尝肠畅昌敞倡偿猖裳鲳氅菖惝嫦徜鬯阊怅伥昶苌娼仧倀倘僘償儻兏厰嘗嚐場塲尙尚廠悵晿暢棖椙淌淐焻玚琩瑒瑺瓺甞畼脹腸膓萇蟐裮誯鋹鋿錩鏛锠長镸閶闛韔鯧
鱨鲿鼚
而在py_file.txt中
const char PY_mb_huan[] ={"欢还环桓缓幻宦唤换涣患焕痪豢"};
这样就可能将huan变为hai,幸亏这样的情况只有以上三个,所以手工调整一下即可
还有一个特例就是“揣”的拼音需要特殊考虑,
得到的文件如下:new_py_file.rar (13.9 KB)
最后,就是再整理了,
/* 按照数字的顺序重新排列数据 */
read_new_file.Open("final-1.txt", CFile::modeRead,NULL);
write_file.Open("final-2.txt", CFile::modeWrite | CFile::modeCreate,NULL);
CString str2="",str3="",str4="",str5="",str6="",str7="",str8="",str9="";
while (read_new_file.ReadString(my_str))
{
char * left_char = my_str.GetBuffer(0);
left_char += 2;
my_str += "\n";
switch(*left_char)
{
case '2':
str2 += my_str;
break;
case '3':
str3 += my_str;
break;
case '4':
str4 += my_str;
break;
case '5':
str5 += my_str;
break;
case '6':
str6 += my_str;
break;
case '7':
str7 += my_str;
break;
case '8':
str8 += my_str;
break;
case '9':
str9 += my_str;
break;
default:
break;
}
}
write_file.WriteString(str2); write_file.WriteString(str3); write_file.WriteString(str4); write_file.WriteString(str5);
write_file.WriteString(str6);
write_file.WriteString(str7);
write_file.WriteString(str8);
write_file.WriteString(str9);
目的是将拼音按数字顺序重新排列,以加快搜索速度
{"2","a",(char *)PY_mb_a},
{"2","b",(char *)PY_mb_bu},
{"2","c",(char *)PY_mb_ca},
{"24","ai",(char *)PY_mb_ai},
{"26","an",(char *)PY_mb_an},
{"26","ao",(char *)PY_mb_ao},
{"22","ba",(char *)PY_mb_ba},
{"24","bi",(char *)PY_mb_bi},
{"26","bo",(char *)PY_mb_bo},
{"28","bu",(char *)PY_mb_bu},
{"22","ca",(char *)PY_mb_ca},
{"23","ce",(char *)PY_mb_ce},
{"24","ci",(char *)PY_mb_ci},
{"28","cu",(char *)PY_mb_cu},
{"264","ang",(char *)PY_mb_ang},
{"224","bai",(char *)PY_mb_bai},
{ final-1.rar (2.28 KB)
final-2.rar (2.44 KB)
最后,就是按照输入的数字顺序,遍历数组,得到相应的拼音和汉字串,我就不多啰嗦了,明天到单位,我把真实的终端拍个照片发上来给大家看一下。
当然,这里面还有些细节问题,比如控制显示啦,搜索的速度啦,有效输入的判断啦,等等。
我这里只是起到抛砖引玉的作用,还希望大家有更好的东西与大家分。