如何在Go中处理控制台输入类型验证?

时间:2019-05-30 20:16:07

标签: validation go user-input

我正在尝试使用循环为程序构建非常基本的控制台输入。但是,当用户输入除整数以外的其他内容时,错误消息将触发与输入字符串中的字符(包括换行符)一样多的次数。

我已经尝试了Scan(),Scanln()以及bufio.NewReader()进行字符串解析,以及在Println()之后使用continue。全部产生相同的结果。

var threads int

func main() {
    fmt.Println("Enter number of threads:")
    for {
        _, err := fmt.Scanln(&threads)
        if err != nil {
            fmt.Println("Enter a valid number")
        } else {
            break
        }
    }
}

用户输入:

  

asd

预期结果:

  

程序:输入一个有效的数字

实际结果:

  

程序:输入一个有效的数字

     

程序:输入一个有效的数字

     

程序:输入一个有效的数字

     

程序:输入一个有效的数字

1 个答案:

答案 0 :(得分:1)

fmt.Scanln(&threads)会引发错误,因为您的第一个字符已经不是有效的int,因此sd\n仍保留在stdin缓冲区中,这是我对另外三个错误的解释。为避免这种情况,您可以阅读字符串,然后像下面的代码一样使用int, err := strconv.Atoi(string)。在此请注意,fmt.Scanfmt.Scanln会将您的用户输入拆分到下一个空格,这可能不适合您的用例。请查看How to read input from console line,以获取有关如何选择适合您的用例的一些见解。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var s string
    var i int
    fmt.Println("Enter number of threads:")
    for {
        _, err := fmt.Scan(&s)
        i, err = strconv.Atoi(s)
        if err != nil {
            fmt.Println("Enter a valid number")
        } else {
            fmt.Println("Got: " + strconv.Itoa(i))
            break
        }
    }
    //Todo
}