用VC++6.0編程實(shí)現(xiàn)漢字拼音查找
eDog[原創(chuàng)]
摘要 使用VC++6.0編程查找漢字的拼音
關(guān)鍵字 漢字,拼音,資源
下載:http://www.shnenglu.com/Files/edog/LookPY.rar
一、 引言
在讀書(shū)看報(bào)或者瀏覽網(wǎng)上文章時(shí)候,經(jīng)常會(huì)看到一些比較生僻的漢字而不知道其讀音;或者有些漢字知道其寫法,可以使用五筆等筆劃輸入法輸入?yún)s不能使用拼音輸入法輸入。本文將演示怎么使用VC++6.0編寫程序?qū)崿F(xiàn)漢字的拼音的查找,對(duì)于多音字也可以把所有的拼音找出來(lái)。在網(wǎng)上看到生僻的漢字時(shí),把漢字粘貼到本程序的輸入框,就可以查找出這些漢字的拼音;或者使用五筆等輸入法把漢字輸入到本程序查找其拼音。可以有助于讀者正確的使用漢語(yǔ)拼音。
二、 基礎(chǔ)知識(shí)
1、本程序?qū)崿F(xiàn)的原理是建立一張對(duì)應(yīng)表,記錄所有漢字和對(duì)應(yīng)的拼音,根據(jù)輸入框中的漢字在此對(duì)應(yīng)表中查找出其拼音,對(duì)于多音字可以查找出多個(gè)拼音,表的結(jié)構(gòu)為拼音在前,用空格或者TAB鍵分隔,具有此讀音的漢字緊跟在后,每個(gè)拼音及其漢字占一行,如下為其中的兩行:
a 啊阿呵吖嗄腌錒錒
ang 昂骯盎仰卬岇昻枊醃醠骯
2、可以把這個(gè)對(duì)應(yīng)表保存在一個(gè)文件中,每次讀取文件進(jìn)行拼音的查找。為了使用上的方便,可以把此文件作為程序資源的一部分,附加在應(yīng)用程序中,以后使用時(shí)只需要一個(gè)應(yīng)用程序就可以正確運(yùn)行了。在程序運(yùn)行時(shí)候根據(jù)資源中的數(shù)據(jù)進(jìn)行查找,而不需要去讀取對(duì)應(yīng)表文件。本例子程序中此對(duì)應(yīng)表的資源類型命名為“PYGBK”,資源的ID為IDR_PYGBK1。操作應(yīng)用程序中的資源需要用到一些Windows API,如下:
HRSRC FindResource(
HMODULE hModule,
LPCTSTR lpName,
LPCTSTR lpType
);
此函數(shù)用于找到程序中的資源,輸入?yún)?shù)分別為程序的實(shí)例句柄、資源名稱和資源類型。返回資源的句柄。
DWORD SizeofResource(
HMODULE hModule,
HRSRC hResInfo
);
此函數(shù)用于得到指定資源的大小,輸入?yún)?shù)分別為程序的實(shí)例句柄和資源的句柄。返回資源大小的字節(jié)數(shù)。
HGLOBAL LoadResource(
HMODULE hModule,
HRSRC hResInfo
);
此函數(shù)用于裝入指定的資源,輸入?yún)?shù)分別為程序的實(shí)例句柄和資源的句柄。返回指向資源數(shù)據(jù)的指針。
以上的Windows API的詳細(xì)使用方法請(qǐng)參考MSDN。
3、在開(kāi)始查找漢字拼音之前,需要判斷輸入的漢字是否合法。比如用戶輸入了英文字符就會(huì)產(chǎn)生錯(cuò)誤信息。對(duì)于簡(jiǎn)體中文漢字來(lái)說(shuō),每個(gè)漢字由兩個(gè)字節(jié)組成,第一個(gè)字節(jié)的范圍為0xA1~0xFF,第二個(gè)字節(jié)的范圍為0x40~0xFF,根據(jù)此條件就可以判斷輸入的字符是否合法,程序上實(shí)現(xiàn)如下:
unsigned char ch = buf[j];

if( (((j+2)%2==0) && ch<0xA1) || (((j+2)%2)==1 && ch<0x40) )


{

// 不合法的字符,返回

}
其中:buf為輸入的漢字字符串(最多10個(gè)漢字20個(gè)字符),j為位移
((j+2)%2==0)表示ch為漢字的第一個(gè)字節(jié)
((j+2)%2==1)表示ch為漢字的第二個(gè)字節(jié)
有關(guān)漢字編碼和拼音的知識(shí)請(qǐng)參考其他文檔。
一、編程實(shí)現(xiàn)
1、 創(chuàng)建一個(gè)基于對(duì)話框的MFC應(yīng)用程序。
2、 制作界面,如下圖1所示:
3、 把漢字拼音對(duì)應(yīng)表導(dǎo)入為資源,定義資源名字為“PYGBK”,自動(dòng)生成資源ID為IDR_PYGBK1,這里需要注意的是在此資源的屬性框中去掉“External file”的選擇(缺省為選擇),這樣對(duì)應(yīng)表才能真正導(dǎo)入到應(yīng)用程序中,達(dá)到與外部文件的分離。
4、 為輸入框定義一個(gè)CString類型的變量m_Edit1,為列表框定義一個(gè)CListBox類型的變量m_List1。
為查找按鈕添加相應(yīng)的關(guān)聯(lián)函數(shù),并在此函數(shù)中添加查找拼音的代碼。具體算法為查找對(duì)應(yīng)表中的所有漢字,如果找到就再查找其拼音并把與此漢字對(duì)應(yīng)的所有拼音顯示在列表框中。下圖2為查找漢字串“蒹葭蒼蒼白露為霜”的結(jié)果。
5、主要函數(shù)代碼:
1
// 查找按鈕對(duì)應(yīng)的函數(shù)
2
void CLookPYDlg::OnSearch()
3

{
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
{
13
ch = m_Edit1.GetAt(j); // 漢字串中的第 i 個(gè)字符
14
// 判斷漢字是否合法
15
if( (((j+2)%2==0) && ch<0xA1) || (((j+2)%2)==1 && ch<0x40) )
16
{
17
MessageBox("輸入了非法的字符!", NULL, MB_ICONWARNING);
18
return;
19
}
20
}
21
22
HRSRC HGBSrc;
23
LPVOID GBTemp;
24
// 查找對(duì)應(yīng)表資源
25
HGBSrc = FindResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_PYGBK1),"PYGBK");
26
if(HGBSrc == NULL) return;
27
// 得到對(duì)應(yīng)表數(shù)據(jù)的大小
28
DWORD size = SizeofResource(AfxGetInstanceHandle(), HGBSrc);
29
// 裝入對(duì)應(yīng)表
30
HGLOBAL m_HGBStr = LoadResource(AfxGetInstanceHandle(), HGBSrc);
31
// 鎖定資源并得到數(shù)據(jù)指針
32
GBTemp = LockResource(m_HGBStr);
33
// 轉(zhuǎn)換為 char 類型的指針
34
char *buf = (char *)GBTemp;
35
36
char hzstr[21], ss[50];
37
strcpy(hzstr, m_Edit1);
38
for(i=0; i<10; i++) arPY[i][0]=0;
39
// 調(diào)用查找拼音的函數(shù)
40
this->SearchHZPY(buf, size, hzstr);
41
// 在列表框中顯示結(jié)果
42
for(i=0; i<strlen(hzstr)/2; i++)
43
{
44
sprintf(ss, "%c%c - %s", hzstr[i*2], hzstr[i*2+1], arPY[i]);
45
m_List1.AddString(ss);
46
}
47
}
48
49
/**//*
50
查找拼音的函數(shù)
51
輸入: buf - 拼音和漢字的對(duì)應(yīng)表數(shù)組
52
size- 此數(shù)組的大小
53
hzstr - 輸入的漢字串,最多10個(gè)漢字
54
返回:true, 結(jié)果保存在 arPY 數(shù)組,arPY 為 10×50的字符數(shù)組,
55
用于保存與漢字對(duì)應(yīng)的所有拼音
56
*/
57
bool CLookPYDlg::SearchHZPY(char *buf, long size, char *hzstr)
58

{
59
char *ptr, str[1000], szPY[10], szHZ[1000];
60
long i, j, k, start=0, len, len2;
61
len2 = strlen(hzstr); // 輸入的漢字串的長(zhǎng)度
62
for(i=0; i<size; i++)
63
{
64
if(buf[i]==0x0a) // 到達(dá)行末
65
{
66
ptr = &buf[start];
67
len = i-start; // 此行的長(zhǎng)度
68
strncpy(str, ptr, len); // 取此行的數(shù)據(jù)
69
str[len]=0;
70
start = i+1; // 定位下一行的開(kāi)始位置
71
72
sscanf(str, "%s %s", szPY, szHZ); // 分離拼音和對(duì)應(yīng)的漢字
73
len=strlen(szHZ);
74
// 循環(huán)查找
75
for(j=0; j<len; j=j+2)
76
{
77
for(k=0; k<len2; k=k+2)
78
{
79
// 找到匹配結(jié)果
80
if(szHZ[j]==hzstr[k] && szHZ[j+1]==hzstr[k+1])
81
{
82
strcat(arPY[k/2], szPY);
83
strcat(arPY[k/2], ", ");
84
}
85
}
86
}
87
}
88
}
89
return true;
90
}
一、 小結(jié)
本文從原理和編程實(shí)現(xiàn)方面簡(jiǎn)單的介紹了漢字拼音查找的方法,并簡(jiǎn)單演示了怎么使用應(yīng)用程序的資源。實(shí)現(xiàn)的關(guān)鍵為建立一張漢字和拼音的對(duì)應(yīng)表并導(dǎo)入到應(yīng)用程序中以達(dá)到應(yīng)用程序與外部文件的分離。本程序在Windows98/2000環(huán)境使用VC++6.0編譯通過(guò)。
