go日常练习,不定期提供golang小项目作为练手。望客官笑纳的同时也提出宝贵意见,纯手工码字不易,您的支持就是我创作的最大动力。
对于每天手机不离手的我们来说,输入法太熟悉了,今天我们就用golang写一个简单的九宫格输入法,这里没有界面,只用了简单的控制台命令行输入。
一.题设
1.模拟手机九宫格输入,默认输入为数字,当输入#表示切换输入法,即数字与英文之间切换。
2.连续输入数字输出不变:例如输入222,输出也是222;但连续按同一个字母按键,输出的则是该按键上的英文字母索引,例如连续输入222,输出则是C。
3.默认输入“/”会结束,后面的内容也不再显示,同样输入特殊字符也不显示。
二.实战步骤
1.首先我们得了解到九宫格上的字母排列(如上图),这里根据字母顺序声明一个最简单的slice,跟高级的可以下一步完善。代码如下:
wordList := []string{"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz”}
2.声明一个接收命令行输入的变量,并等待接收输入,这里用到了”fmt.Scanln”,这是go标准库fmt下的函数,一共有三个,分别是:fmt.Scan、fmt.Scanf、fmt.Scanln,具体用法可以参考go官方文档。
inputWords := ""
fmt.Scanln(&inputWords)
3.声明一个切换状态,这里用bool值表示,同时再声明输出变量,string类型
switchWords := true
outFrint := ""
4.准备工作做好以后,我们开始监控控制台输入,为了保持控制台一直等待输入,这里使用for循环一直等待的方式,直到控制台输入回车就结束。
for i := 0; i < len(inputWords); i++ {
}
5.接下来我们先考虑跳出循环的条件,这里优先考虑,例如题干中的输入”/“就结束,看到结束我想大家知道该用什么词了吧。
if string(inputWords[i]) == "/" {
break
}
6.开关控制,数字与英文之间的开关切换,注意这里要用到continue,因为输入“#”以后只是切换输入法,并没有实际操作,因此直接continue即可。
if string(inputWords[i]) == "#" {
switchWords = !switchWords
continue
}
7.接下来首先处理数字的输出,这是最简单的。这里用到“strconv.Atoi”函数,将输入的字符串转化成数字,当err不为nil时表示转换失败,那就表示输入的字符串不是数字,直接退出。
if switchWords {
num, err := strconv.Atoi(string(inputWords[i]))
if err != nil { //非数字直接退出,这里做个异常处理
continue
}
outFrint += fmt.Sprintf("%d", num)
}
8.接下来该处理英文的输出,这里要注意的是连续按下某个数字,要输出这个数字上的应对应的英文字母,例如连续输入222,输出的是C;因此要对输入的内容进行遍历比较。
else {
index, err := strconv.Atoi(string(inputWords[i]))
if err != nil { //非数字直接退出
continue
}
if index-2 < -1 { //异常提示,请输入0-9的数字
index = 0
} else if index-2 == -1 {
outFrint += ","
} else {
haveSame := false
sameNum := 0
for j := i + 1; j < len(inputWords); j++ {
if string(inputWords[j]) == "#" {
break
}
if inputWords[j] == inputWords[i] && inputWords[j-1] == inputWords[i] {
haveSame = true
sameNum++
}
}
if haveSame {
outFrint += fmt.Sprintf("%s", string(wordList[index-2][sameNum%3]))
i += sameNum
continue
} else {
outFrint += fmt.Sprintf("%s", string(wordList[index-2][0]))
}
}
}
9.输出字符串
fmt.Println("out:", outFrint)
10.最后附上完整代码,一共67行,大家可以复制到自己的IDE里,然后命名为main.go,然后运行即可:go run main.go;然后再控制台输入数字或者字符即可实现九宫格功能。
package main
import (
"fmt"
"strconv"
)
func main() {
inputWords := ""
switchWords := true
outFrint := ""
wordList := []string{"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}
fmt.Scanln(&inputWords)
for i := 0; i < len(inputWords); i++ {
if string(inputWords[i]) == "/" {
break
}
if string(inputWords[i]) == "#" {
switchWords = !switchWords
continue
}
if switchWords {
num, err := strconv.Atoi(string(inputWords[i]))
if err != nil { //非数字直接退出
continue
}
outFrint += fmt.Sprintf("%d", num)
} else {
index, err := strconv.Atoi(string(inputWords[i]))
if err != nil { //非数字直接退出
continue
}
if index-2 < -1 { //异常提示,请输入0-9的数字
index = 0
} else if index-2 == -1 {
outFrint += ","
} else {
haveSame := false
sameNum := 0
for j := i + 1; j < len(inputWords); j++ {
if string(inputWords[j]) == "#" {
break
}
if inputWords[j] == inputWords[i] && inputWords[j-1] == inputWords[i] {
haveSame = true
sameNum++
}
}
if haveSame {
outFrint += fmt.Sprintf("%s", string(wordList[index-2][sameNum%3]))
i += sameNum
continue
} else {
outFrint += fmt.Sprintf("%s", string(wordList[index-2][0]))
}
}
}
}
fmt.Println("out:", outFrint)
}
ps:如果代码无法运行,请私信本人,本人拷给你一份详细代码。其实合理还有一种情况:输入1的时候的显示,这个时候应该显示小数点或者"@",这里留给大家去添加。