系统功能: 手机的汉语拼音输入法很'聪明',只要用数字键组合,就能够自动找到能组成拼音的字母组合.从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,直到用户选择退出。 注意:这里只列出了一些主要函数,其他功能函数由程序员自行设计。要求每个函数均要做好单体测试后再加入工程中。

评论