系統功能:
手機的漢語拼音輸入法很'聰明',只要用數字鍵組合,就能夠自動找到能組成拼音的字母組合.從2開始分別代表2:abc,3:def,4:ghi,5:jkl,6:mno,7:pqrs,8:tuv,9:wxyz"
鍵盤布局如圖示 +-------+-------+-------+
|1 OK |2 abc |3 def |
+-------+-------+-------+
|4 ghi |5 jkl |6 mno |
+-------+-------+-------+
|7 pqrs |8 tuv |9 wxyz |
+-------+-------+-------+
|#<prep>|0<back>|*<next>|
+-------+-------+-------+
拼音規則:輸入時手機有3個狀態:
1. 拼音狀態: 只接受2至9,和結束鍵1。按下1則進入狀態2,如果候選拼音組合唯一則自動進入狀態3(此時拼音不必拼完);如果無匹配的拼音組合,則一直忽略直到遇到#取消當前拼音。若用戶輸入非法字符,則自動屏蔽非法字符,只讀取合法字符。若只輸入結束鍵1,表示用戶選擇離開。
2. 選擇拼音狀態 : 根據用戶輸入的數字組合,在屏幕上列出滿足條件的拼音組合,每頁最多有10個組合,按字母順序標號由0到9。接受0-9任何一個鍵則選擇對應組合進入狀態3。忽略選擇不存在組合的位置的數字。接受*則下翻一頁。如果已經到達最后一頁則忽略*號。接受#則取消當前拼音,并回到狀態1。
3. 漢字選擇狀態: 進入本狀態,如果所選的拼音組合包含對應漢字。則可以選擇漢字。否則回到狀態1,并且此時不輸出任何漢字。每頁最多有10個漢字,按輸入的數據順序排列。接受0-9任何一個鍵則選擇對應漢字并輸出輸出后回到拼音狀態。忽略選擇不存在組合的位置的數字。接受#則取消當前拼音,并回到狀態1。
注意:提供一個文本文件,里面包含所有的漢語拼音及對應漢字。文件包含若干行,每行2個字符串,串之間有1個空格分開。行尾沒有空格。第一個串只包含英文字母,表示一個有效的拼音發音組合。后一個串包含若干個漢字。每個漢字是2個字節組成的。第一個字節最高位為1,第二個字節在0x40到0xfe之間,且不為0x7f。
總體設計:
一。讀取文件信息
1。從文件中把所有漢語拼音及對應漢字讀入內存。因為文件中的每個拼音及其所有同音字處在同一行中,故可用一個指針數組*storage[]存儲文件內容,數組的每個元素指向文件中的一行。
二。讀取用戶數據
2。讀取用戶輸入的字符串,并對其進行適當的轉換,判斷字符串是否合法,并屏蔽非法字符得到一個只包含合法數字字符的新字符串。
三。處理用戶數據,并請用戶選擇正確的拼音和漢字
3。采用遞歸的方法,求出數字字符串對應的所有拼音組合,把所有滿足條件的拼音組合添加到線性鏈表letterList。
4。把匹配的拼音組合按順序顯示到屏幕,請用戶選取一個組合。
5。根據選中的拼音組合,到*storage[]中找到相應的漢字,并按順序輸出到屏幕,請用戶選取一個漢字。
6。輸出用戶選取的漢字,同時輸出到文件。
四。重復步驟2-6,直到用戶選擇退出。
詳細設計:
一。讀取文件信息
1。從文件中把所有漢語拼音及對應漢字讀入內存。因為文件中的每個拼音及其所有同音字處在同一行中,故可用一個指針數組*storage[]存儲文件內容,數組的每個元素指向文件中的一行。因為工程中很多函數都要用到指針數組*storage[],因此把它設置成全局變量。
實現函數:void ReadFile(const char fileName[]);
/*
函數聲明:void ReadFile(const char fileName[]);
函數功能:從指定的文件中把所有漢語拼音及對應漢字讀入一個指針數組*storage[](全局變量),
數組的每個元素指向文件中的一行。
輸入變量: const char fileName[],指定的文件名,其中存儲了漢字庫
輸出變量:*storage[],全局變量,每個元素指向一個包含某拼音組合及其對應漢字的字符串
返回值: 無
*/
二。讀取用戶數據
2。讀取用戶輸入的字符串buf,并對其進行適當的轉換,判斷字符串是否合法,并屏蔽非法字符得到一個只含合法數字字符的新字符串value。
轉換規則:先找到結束鍵'1',刪除結束鍵之后的字符。若無結束鍵'1',value[i] = '\0';并結束程序;
然后在buf中逆序查找#號,直到找到#號或遇到buf的第一個元素為止。若找到#號,則把#號之后的合法字符(數字)復制到value;
若未找到#號,則把buf的所有合法字符(數字)復制到value;若只輸入結束鍵'1',表示用戶選擇離開。
實現函數:void ReadValue(char value[]);
/*
函數聲明:void ReadValue(char value[]);
函數功能:讀取用戶輸入的字符串buf,并對其進行適當的轉換。
轉換規則:先找到結束鍵'1',刪除結束鍵之后的字符。
若無結束鍵'1',value[i] = '\0';;并結束程序;
然后在buf中逆序查找#號,直到找到#號或遇到buf的第一個元素為止。
若找到#號,則把#號之后的合法字符(數字)復制到value;
若未找到#號,則把buf的所有合法字符(數字)復制到value;
若只輸入結束鍵'1',表示用戶選擇離開。
輸入變量: char value[],用來存儲用戶輸入的合法字符的字符串
輸出變量: char value[],用來存儲用戶輸入的合法字符的字符串
返回值: 無
*/
三。處理用戶數據,并請用戶選擇正確的拼音和漢字
此部分可分成三個步驟:先分析并得到正確的拼音組合,再根據拼音組合得到正確的漢字,最后輸出該漢字。
3。 獲取正確的拼音組合:(若value[0] = '\0';,則跳到第6步)
實現函數:void OutPutSpell(char letters[],const char value[]);
/*
函數聲明:void OutPutSpell(char letters[],const char value[]);
函數功能:根據整理后得到的字符串value,找出對應的所有拼音組合,創建一個線性鏈表letterList,
把所有滿足條件的拼音組合添加到letterList。把存儲在letterList中的拼音組合按順序顯示到屏幕,
請用戶選取一個組合,并把用戶選擇的拼音存儲到letters。 然后銷毀線性鏈表。
輸入變量:char letters[],用來存儲用戶選擇的拼音組合
const char value[],用來存儲用戶輸入的合法字符的字符串
輸出變量:char letters[],用來存儲用戶選擇的拼音組合
返回值: 無
*/
該函數包括四個主要功能函數:
LNode GetLetterList(const char value[]);
void ChooseSpell(LNode head, char letters[]);
void RecursionAnalyse(const char *keyboard[], const char value[], int pos, char buf[], LNode Head);
void DistroyList(LNode List);
/*
函數聲明:LNode GetLetterList(const char value[]);
函數功能:首先創建一個指針數組用來存儲鍵盤上的數字字母組合,以該數字為下標,即
const char *keyboard[10] = {NULL, NULL,"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
創建一個空的線性鏈表LNode letterList。
然后調用函數RecursionAnalyse,采用遞歸的方法,求出數字字符串對應的所有拼音組合,并把它們添加到鏈表letterList。
輸入變量: const char value[],用來存儲用戶輸入的合法字符的字符串
輸出變量: 無
返回值: LNode letterList,由拼音組合所組成的鏈表,它的空間在程序執行過程中動態分配
*/
/*
函數聲明:void ChooseSpell(LNode head, char letters[]);
函數功能:把存儲在鏈表letterList中的拼音組合按順序顯示到屏幕,請用戶選取一個組合,
若用戶輸入#號存儲letters[0] = '\0';
若用戶輸入*號,則繼續輸出后面的拼音組合,直到全部輸出';
若用戶輸入了有效的選擇,存儲所選擇的拼音組合到letters。
若用戶輸入非法字符或在末頁輸入*號,報錯并要求重新輸入。
輸入變量:LNode Head,線性鏈表letterList 的頭結點
char letters[],用來存儲用戶選擇的拼音組合
輸出變量:char letters[],用來存儲用戶選擇的拼音組合
返回值: 無
*/
/*
函數聲明:void RecursionAnalyse(const char *keyboard[], const char value[], int pos, char buf[], LNode Head);
函數功能:遞歸調用本函數,求出所有的拼音組合,每求出一個拼音組合便將其構造成一個字符串,
把該字符串作為結點數據插入鏈表letterList。
輸入變量: const char *keyboard[],用來存儲手機鍵盤信息的指針數組,根據輸入的數字可以得到相應的字母
const char value[],用來存儲用戶輸入的合法字符的字符串
int pos, 當前所處理的value的元素的下標
LNode Head,線性鏈表letterList 的頭結點
輸出變量: LNode Head,線性鏈表letterList 的頭結點
返回值: 無
*/
/*
函數聲明:void DistroyList(LNode List);
函數功能:銷毀鏈表letterList。
輸入變量:LNode *List,指向線性鏈表letterList的指針
輸出變量:無
返回值: 無
*/
4。獲取正確的漢字:(若letters[0] = '\0',則跳到第6步)
實現函數:void OutPutCharacters(const char letters[], char characters[]);
/*
函數聲明:void OutPutCharacters(const char letters[], char character[]);
函數功能:到*storage[]中找到與letters匹配的元素,將相應的漢字按順序輸出到屏幕,
請用戶選取一個漢字,
若用戶輸入#號或非法字符,存儲NULL到character;
若用戶輸入*號,則繼續輸出后面的漢字,直到全部輸出,然后存儲NULL到character;
若用戶輸入了有效的選擇,存儲所選擇的漢字到character。
輸入變量:const char letters[],用來存儲用戶選擇的拼音組合
char character[],用來存儲用戶選擇的漢字
輸出變量:char character[],用來存儲用戶選擇的漢字
返回值: 無
*/
該函數包括三個主要功能函數:
int MatchCharacters(const char letters[], int pos);
void SaveCharacters(char charactersStorage[][3], char source[]);
void ChooseCharacters(char character[], const char charactersStorage[][3]);
/*
函數聲明:int MatchCharacters(const char letters[], int pos);
函數功能:判斷storage[pos]中的拼音組合是否與字符串letters相同
輸入變量: const char letters[],用來存儲用戶選擇的拼音字符串
int pos, 當前所處理的storage的指針元素的下標
輸出變量:無
返回值: 相同則返回1,否則返回0
*/
/*
函數聲明:void SaveCharacters(char charactersStorage[][3], char source[]);
函數功能:把source中的漢字存儲到charactersStorage中
輸入變量:char charactersStorage[][3], 用來存儲與拼音letters對應的所有漢字
char source[], storage的一個指針元素,它的拼音部分與letters相同
輸出變量: char charactersStorage[][3], 用來存儲與拼音letters對應的所有漢字
返回值:無
*/
/*
函數聲明:void ChooseCharacters(char character[], const char charactersStorage[][3]);
函數功能:把存儲在charactersStorage中的漢字按順序顯示到屏幕,請用戶選取一個組合,
若用戶輸入#號存儲character[0] = '\0';
若用戶輸入*號,則繼續輸出后面的漢字,直到全部輸出';
若用戶輸入了有效的選擇,存儲所選擇的漢字到character。
若用戶輸入非法字符或在末頁輸入*號,報錯并要求重新輸入。
輸入變量:char character[],用來存儲用戶選擇的漢字
const char charactersStorage[][3],用來存儲所有同音字
輸出變量:char character[],用來存儲用戶選擇的漢字
返回值: 無
*/
5。顯示用戶選取的漢字到屏幕,同時按照追加的方式輸出到指定文件 。
實現函數:void PrintCharacter(const char character[], const char fileName[]);
/*
函數聲明:void PrintCharacter(const char character[], const char fileName[]);
函數功能:顯示用戶選取的漢字到屏幕,同時按照追加的方式輸出到指定文件 。
輸入變量:const char character[],用來存儲用戶選擇的漢字
const char fileName[],指定的文件名,用來追加存儲用戶選擇的漢字
輸出變量:char character[],用來存儲用戶選擇的漢字
返回值: 無
*/
6。重復步驟2-5,直到用戶選擇退出。
注意:這里只列出了一些主要函數,其他功能函數由程序員自行設計。要求每個函數均要做好單體測試后再加入工程中。