用VC++6.0編程實現漢字拼音查找
eDog[原創]
摘要 使用VC++6.0編程查找漢字的拼音
關鍵字 漢字,拼音,資源
下載:http://www.shnenglu.com/Files/edog/LookPY.rar
一、 引言
在讀書看報或者瀏覽網上文章時候,經常會看到一些比較生僻的漢字而不知道其讀音;或者有些漢字知道其寫法,可以使用五筆等筆劃輸入法輸入卻不能使用拼音輸入法輸入。本文將演示怎么使用VC++6.0編寫程序實現漢字的拼音的查找,對于多音字也可以把所有的拼音找出來。在網上看到生僻的漢字時,把漢字粘貼到本程序的輸入框,就可以查找出這些漢字的拼音;或者使用五筆等輸入法把漢字輸入到本程序查找其拼音??梢杂兄谧x者正確的使用漢語拼音。
二、 基礎知識
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];

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


{

// 不合法的字符,返回

}
其中: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

{
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 個字符
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
// 查找對應表資源
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
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
{
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
查找拼音的函數
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

{
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
{
64
if(buf[i]==0x0a) // 到達行末
65
{
66
ptr = &buf[start];
67
len = i-start; // 此行的長度
68
strncpy(str, ptr, len); // 取此行的數據
69
str[len]=0;
70
start = i+1; // 定位下一行的開始位置
71
72
sscanf(str, "%s %s", szPY, szHZ); // 分離拼音和對應的漢字
73
len=strlen(szHZ);
74
// 循環查找
75
for(j=0; j<len; j=j+2)
76
{
77
for(k=0; k<len2; k=k+2)
78
{
79
// 找到匹配結果
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
}
一、 小結
本文從原理和編程實現方面簡單的介紹了漢字拼音查找的方法,并簡單演示了怎么使用應用程序的資源。實現的關鍵為建立一張漢字和拼音的對應表并導入到應用程序中以達到應用程序與外部文件的分離。本程序在Windows98/2000環境使用VC++6.0編譯通過。
