【问题标题】:How to handle console input type validation in Go?如何在 Go 中处理控制台输入类型验证?
【发布时间】:2019-06-01 00:42:11
【问题描述】:

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

我已经尝试过 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

预期结果:

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

实际结果:

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

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

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

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

【问题讨论】:

  • 您检查过实际返回的错误是什么吗?您正在检查它是否为 nil,但您没有检查该值。
  • 是的,我检查了它们。对于字符,它是“预期的整数”,对于换行符是“意外的换行符”。这是可以预测的,但我仍然不明白为什么它会在继续之前多次触发 iferr 语句为真。

标签: validation go user-input


【解决方案1】:

fmt.Scanln(&threads) 抛出一个错误,因为您的第一个 char 已经不是有效的 int,因此在 stdin 缓冲区中仍保留有 sd\n,这将是我对另外三个错误的解释。为避免这种情况,您可以只读取字符串,然后使用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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多