go语言读取控制台输入 | 青训营笔记

100 阅读3分钟

这个是使用go语言实现的一个猜数字的小游戏,本身没有什么难点,但也不能马虎,一点小细节就可以让我改bug改一下午,总之细心很重要,接下来一块来看看这点小细节。

使用bufio中读取标准输入

bufio包可以读取标准输入,代码如下:

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
)

func main() {
	maxNum := 100
	secretNumber := rand.Intn(maxNum)

	for {
		fmt.Println("输入你猜测的数字:")
		reader := bufio.NewReader(os.Stdin)
		s_in, err := reader.ReadString('\n')//需要以“\n”换行符作为分隔符
		if err != nil {
			fmt.Println("出现了异常,请重新输入", err)
			continue
		}
		sin := string(s_in[:len(s_in)-2])
                //因为在windows系统下换行符包括“\r\n”,故这里需要去除这两个字符,否则下面的字符串转数字会报错,在这里卡了好久
		guess, err := strconv.Atoi(sin)
		if err != nil {
			fmt.Println("请输入整数", err)
			continue
		}
		fmt.Println("你猜的数是", guess)
		if guess > secretNumber {
			fmt.Println("猜大了,再试试")
			continue
		} else if guess < secretNumber {
			fmt.Println("猜小了,再试试")
			continue
		} else {
			fmt.Println("恭喜你,猜对了")
			break
		}
	}
}

bufio包是对IO的封装,可以操作文件等内容,同样可以用来接收键盘的输入,此时对象不是文件等,而是os.Stdin,也就是标准输入设备。

bufio包含了Reader、Writer、Scanner等对象,封装了很多对IO内容的处理方法,但应对键盘输入来说,使用Reader对象(或Scanner对象)即可,其他略。

其中NewReader()创建一个bufio.Reader实例,表示创建一个从给定文件中读取数据的读取器对象。然后调用读取器对象(Reader实例)的ReadString()方法,这个方法以\n作为分隔符,它的分隔符必须只能是单字符,且必须使用单引号包围,因为它会作为byte读取。ReadString()读取来自os.Stdin的内容后将其保存到input变量中,同时返回是否出错的信息。ReadString()只有一种情况会返回err:没有遇到分隔符。

ReadString会将读取的内容包括分隔符都一起放进缓冲中,如果读取文件时读到了结尾,则会将整个文件内容放进缓冲,并将文件终止标识符io.EOF放进设置为err。

但需要注意的是,在windows系统中,换行符包括“\r\n”,在得到控制台输入的字符串后,还需要将“\r\n”都去掉,若只去除“\n”的话,得到的字符串还包括“\r”在进行后续操作很可能会报错,比如我是要读取从控制台中输入的数字,一开始去除了“\n”字符,再使用strconv.Atoi(sin)转为数字是总是报错,转换失败,我百思不得其解,各种百度,最后输出了一下错误信息,才发现还有一个“\r”字符在,影响了我的字符转换(早知道就不该只输出一个错误提醒,应该把报错信息给打印出来)。

通过这个小游戏,可以告诉我们,平时写代码一定要细心再细心,出粗了要仔细检查代码。