用VC++6.0编程实现汉字拼音查找
eDog[原创]
摘要 使用VC++6.0编程查找汉字的拼音
关键字 汉字,拼音,资源
下载:http://www.cppblog.com/Files/edog/LookPY.rar
一、 引言
在读书看报或者浏览网上文章时候,经常会看到一些比较生僻的汉字而不知道其读音;或者有些汉字知道其写法,可以使用五笔等笔划输入法输入却不能使用拼音输入法输入。本文将演示怎么使用VC++6.0编写程序实现汉字的拼音的查找,对于多音字也可以把所有的拼音找出来。在网上看到生僻的汉字时,把汉字粘贴到本程序的输入框,就可以查找出这些汉字的拼音;或者使用五笔等输入法把汉字输入到本程序查找其拼音。可以有助于读者正确的使用汉语拼音。
二、 基础知识
1、本程序实现的原理是建立一张对应表,记录所有汉字和对应的拼音,根据输入框中的汉字在此对应表中查找出其拼音,对于多音字可以查找出多个拼音,表的结构为拼音在前,用空格或者TAB键分隔,具有此读音的汉字紧跟在后,每个拼音及其汉字占一行,如下为其中的两行:
a 啊阿呵吖嗄腌锕錒
ang 昂肮盎仰卬岇昻枊醃醠骯
2、可以把这个对应表保存在一个文件中,每次读取文件进行拼音的查找。为了使用上的方便,可以把此文件作为程序资源的一部分,附加在应用程序中,以后使用时只需要一个应用程序就可以正确运行了。在程序运行时候根据资源中的数据进行查找,而不需要去读取对应表文件。本例子程序中此对应表的资源类型命名为“PYGBK”,资源的ID为IDR_PYGBK1。操作应用程序中的资源需要用到一些Windows API,如下:
HRSRC FindResource(
HMODULE hModule,
LPCTSTR lpName,
LPCTSTR lpType
);
此函数用于找到程序中的资源,输入参数分别为程序的实例句柄、资源名称和资源类型。返回资源的句柄。
DWORD SizeofResource(
HMODULE hModule,
HRSRC hResInfo
);
此函数用于得到指定资源的大小,输入参数分别为程序的实例句柄和资源的句柄。返回资源大小的字节数。
HGLOBAL LoadResource(
HMODULE hModule,
HRSRC hResInfo
);
此函数用于装入指定的资源,输入参数分别为程序的实例句柄和资源的句柄。返回指向资源数据的指针。
以上的Windows API的详细使用方法请参考MSDN。
3、在开始查找汉字拼音之前,需要判断输入的汉字是否合法。比如用户输入了英文字符就会产生错误信息。对于简体中文汉字来说,每个汉字由两个字节组成,第一个字节的范围为0xA1~0xFF,第二个字节的范围为0x40~0xFF,根据此条件就可以判断输入的字符是否合法,程序上实现如下:
unsigned char ch = buf[j];
![](/Images/OutliningIndicators/None.gif)
if( (((j+2)%2==0) && ch<0xA1) || (((j+2)%2)==1 && ch<0x40) )
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
// 不合法的字符,返回
![](/Images/OutliningIndicators/InBlock.gif)
}
其中:buf为输入的汉字字符串(最多10个汉字20个字符),j为位移
((j+2)%2==0)表示ch为汉字的第一个字节
((j+2)%2==1)表示ch为汉字的第二个字节
有关汉字编码和拼音的知识请参考其他文档。
一、编程实现
1、 创建一个基于对话框的MFC应用程序。
2、 制作界面,如下图1所示:
3、 把汉字拼音对应表导入为资源,定义资源名字为“PYGBK”,自动生成资源ID为IDR_PYGBK1,这里需要注意的是在此资源的属性框中去掉“External file”的选择(缺省为选择),这样对应表才能真正导入到应用程序中,达到与外部文件的分离。
4、 为输入框定义一个CString类型的变量m_Edit1,为列表框定义一个CListBox类型的变量m_List1。
为查找按钮添加相应的关联函数,并在此函数中添加查找拼音的代码。具体算法为查找对应表中的所有汉字,如果找到就再查找其拼音并把与此汉字对应的所有拼音显示在列表框中。下图2为查找汉字串“蒹葭苍苍白露为霜”的结果。
5、主要函数代码:
1
// 查找按钮对应的函数
2
void CLookPYDlg::OnSearch()
3![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
4
m_List1.ResetContent();
5
UpdateData();
6
m_Edit1.TrimLeft();
7
m_Edit1.TrimRight();
8
if(m_Edit1.IsEmpty()) return;
9
UINT i;
10
unsigned char ch;
11
for(int j=0; j<m_Edit1.GetLength(); j++)
12![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13
ch = m_Edit1.GetAt(j); // 汉字串中的第 i 个字符
14
// 判断汉字是否合法
15
if( (((j+2)%2==0) && ch<0xA1) || (((j+2)%2)==1 && ch<0x40) )
16![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17
MessageBox("输入了非法的字符!", NULL, MB_ICONWARNING);
18
return;
19
}
20
}
21![](/Images/OutliningIndicators/InBlock.gif)
22
HRSRC HGBSrc;
23
LPVOID GBTemp;
24
// 查找对应表资源
25
HGBSrc = FindResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_PYGBK1),"PYGBK");
26
if(HGBSrc == NULL) return;
27
// 得到对应表数据的大小
28
DWORD size = SizeofResource(AfxGetInstanceHandle(), HGBSrc);
29
// 装入对应表
30
HGLOBAL m_HGBStr = LoadResource(AfxGetInstanceHandle(), HGBSrc);
31
// 锁定资源并得到数据指针
32
GBTemp = LockResource(m_HGBStr);
33
// 转换为 char 类型的指针
34
char *buf = (char *)GBTemp;
35![](/Images/OutliningIndicators/InBlock.gif)
36
char hzstr[21], ss[50];
37
strcpy(hzstr, m_Edit1);
38
for(i=0; i<10; i++) arPY[i][0]=0;
39
// 调用查找拼音的函数
40
this->SearchHZPY(buf, size, hzstr);
41
// 在列表框中显示结果
42
for(i=0; i<strlen(hzstr)/2; i++)
43![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
44
sprintf(ss, "%c%c - %s", hzstr[i*2], hzstr[i*2+1], arPY[i]);
45
m_List1.AddString(ss);
46
}
47
}
48![](/Images/OutliningIndicators/None.gif)
49![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*
50
查找拼音的函数
51
输入: buf - 拼音和汉字的对应表数组
52
size- 此数组的大小
53
hzstr - 输入的汉字串,最多10个汉字
54
返回:true, 结果保存在 arPY 数组,arPY 为 10×50的字符数组,
55
用于保存与汉字对应的所有拼音
56
*/
57
bool CLookPYDlg::SearchHZPY(char *buf, long size, char *hzstr)
58![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
59
char *ptr, str[1000], szPY[10], szHZ[1000];
60
long i, j, k, start=0, len, len2;
61
len2 = strlen(hzstr); // 输入的汉字串的长度
62
for(i=0; i<size; i++)
63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
64
if(buf[i]==0x0a) // 到达行末
65![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
66
ptr = &buf[start];
67
len = i-start; // 此行的长度
68
strncpy(str, ptr, len); // 取此行的数据
69
str[len]=0;
70
start = i+1; // 定位下一行的开始位置
71![](/Images/OutliningIndicators/InBlock.gif)
72
sscanf(str, "%s %s", szPY, szHZ); // 分离拼音和对应的汉字
73
len=strlen(szHZ);
74
// 循环查找
75
for(j=0; j<len; j=j+2)
76![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
77
for(k=0; k<len2; k=k+2)
78![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
79
// 找到匹配结果
80
if(szHZ[j]==hzstr[k] && szHZ[j+1]==hzstr[k+1])
81![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
82
strcat(arPY[k/2], szPY);
83
strcat(arPY[k/2], ", ");
84
}
85
}
86
}
87
}
88
}
89
return true;
90
}
一、 小结
本文从原理和编程实现方面简单的介绍了汉字拼音查找的方法,并简单演示了怎么使用应用程序的资源。实现的关键为建立一张汉字和拼音的对应表并导入到应用程序中以达到应用程序与外部文件的分离。本程序在Windows98/2000环境使用VC++6.0编译通过。
![11.jpg](/images/cppblog_com/edog/11.jpg)