GO语言工程实践课后作业 | 青训营

87 阅读1分钟

随机数——猜数字案例

之前的代码实现:

import (
    "bufio"
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "strings"
)
​
func main() {
    maxNUm := 100
    secretNum := rand.Intn(maxNUm)
​
    fmt.Println("Please input your guess")
    reader := bufio.NewReader(os.Stdin)
    for {
        input, err := reader.ReadString('\n')
        if err != nil {
            fmt.Println("err!!!")
            continue
        }
​
        input = strings.TrimSuffix(input, "\r\n")
​
        guess, err1 := strconv.Atoi(input)
​
        if err1 != nil {
            fmt.Println("input err!", err1)
            continue
        }
        fmt.Println("your guess is ", guess)
        if guess > secretNum {
            fmt.Println("big!")
        } else if guess < secretNum {
            fmt.Println("little!")
        } else {
            fmt.Println("yes")
            break
        }
​
    }
}

缺陷:从系统os里获取reader输入读取对象,然后进行一系列字符串的操作,变量接收等等,能不能简化这一过程呢?

优化:

fmt.Scanf的用法:

使用fmt.Scanf直接读取用户输入,并且解析为整数。这样就避免了使用bufio.NewReader和字符串处理的过程,代码变得更加简洁。同时,也可以处理输入错误并向用户提供相应的提示。

func main() {
    rand.Seed(time.Now().UnixNano())
    maxNUm := 100
    secretNum := rand.Intn(maxNUm)
​
    fmt.Println("Please input your guess")
    // reader := bufio.NewReader(os.Stdin)
    var guess int
    for {
        // input, err := reader.ReadString('\n')
        _, err := fmt.Scanf("%d", &guess)
        if err != nil {
            fmt.Println("err!!!")
            continue
        }
        // input = strings.TrimSuffix(input, "\r\n")
        // guess, err := strconv.Atoi(input)
        if err != nil {
            fmt.Println("input err!")
        }
        if guess > secretNum {
            fmt.Println("big!")
        } else if guess < secretNum {
            fmt.Println("little!")
        } else {
            fmt.Println("yes")
            break
        }
    }
}

这里运行时会出现一个bug:

unexpected newline

原因:

scanf换行的时候停止扫描,我们每猜一个数字,都会打一个回车键,然后windows的回车键对应的字符其实是:"\r\n",而scanf只是会遇到单纯的"\n"停止,那么前面的"\r"就会出错。直接忽略即可。