go fmt.Scan Scanf Scanln的一个小问题

本文探讨了Go语言中fmt.Scan在非数字输入时的问题及解决方案。当用户输入非预期的字符时,fmt.Scan会反复执行错误处理逻辑。文章最终通过使用bufio包成功解决了这一问题。

bug记录

Scan,Scanf,Scanln的一个问题

go的fmt.Scan在使用中的一个小问题,如下:

for{
    fmt.Println("请选择:1-剪刀 2-石头 3-布 ,0-不玩了")
    count, err := fmt.Scan(&people)
    if err != nil {
        fmt.Println(err)
        fmt.Printf("count:%d\n", count)
        fmt.Println("您的输入有误,请重新输入")
        continue
    }
    //其他逻辑代码
}

这段代码在我正常输入数字的情况下是没有问题的,可以正常获取数值,但是输入非数字的情况下,就会出现,“输入多少个字符,if块里的错误代码就会执行多少遍的情况。”

请选择:1-剪刀 2-石头 3-布 ,0-不玩了
1
您出的是[剪刀],电脑出的是[布]
***********您输了!!***********
请选择:1-剪刀 2-石头 3-布 ,0-不玩了
ab
expected integer
count:0您的输入有误,请重新输入
请选择:1-剪刀 2-石头 3-布 ,0-不玩了
expected integer
count:0您的输入有误,请重新输入
请选择:1-剪刀 2-石头 3-布 ,0-不玩了
abc
expected integer
count:0您的输入有误,请重新输入
请选择:1-剪刀 2-石头 3-布 ,0-不玩了
expected integer
count:0您的输入有误,请重新输入
请选择:1-剪刀 2-石头 3-布 ,0-不玩了
expected integer
count:0您的输入有误,请重新输入
请选择:1-剪刀 2-石头 3-布 ,0-不玩了

感觉是continue之后fmt.Scan()函数并没有重新从标准输入里读取,而是读取到了第一次输入的整个字符串中的下一个字符。
更换使用Scanln或者Scanf后,问题同样存在。

最后采用bufio.NewReader才彻底解决。

for{
    fmt.Println("请选择:1-剪刀 2-石头 3-布 ,0-不玩了")
    stdin := bufio.NewReader(os.Stdin)
    count, err := fmt.Fscan(stdin, &people)
    stdin.ReadString('\n')
    if err != nil {
        fmt.Println(err)
        fmt.Printf("count:%d\n", count)
        fmt.Println("您的输入有误,请重新输入")
        continue
    }
    //其他逻辑代码
}
### Go语言 `fmt` 包下的输入函数及其条件判断 在Go语言中,`fmt` 包提供了多种用于处理输入输出的功能。对于用户输入的读取,主要使用的是 `fmt.Scan`, `fmt.Scanf`, 和 `fmt.Scanln` 函数[^1]。 针对给定的例子,在循环结构中利用 `fmt.Scanln` 获取用户输入并结合条件判断来控制程序流程: ```go package main import ( "fmt" ) func main() { var a int var b string for { fmt.Println("请输入一个整数和一个字符串(用空格分隔,并按回车结束):") if _, err := fmt.Scanln(&a, &b); err != nil || (len(b) == 0 && a == 0){ fmt.Println("错误:无效输入,请重新尝试.") continue // 如果遇到错误或者输入为空,则提示重试 } // 输出结果前先做一些简单的验证 if isValidInput(a, b) { break // 当满足特定条件时退出循环 } else { fmt.Println("注意: 输入不符合预期的要求!") } fmt.Println("整数:", a) fmt.Println("字符串:", b) } fmt.Println("最终接收的数据为:") fmt.Printf("整数=%d 字符串='%s'\n", a, b) } // 定义一个辅助函数来进行额外的输入有效性检查 func isValidInput(num int, str string) bool { return num >= 0 && len(str) > 0 // 假设这里定义有效输入的标准是非负整数加上非空字符串 } ``` 上述代码实现了如下特性: - 使用 `if` 结构捕获可能发生的任何输入错误。 - 对于无效输入(例如只按下Enter键),提供反馈信息并允许用户再次尝试。 - 添加了一个自定义的有效性检验逻辑,确保只有当输入符合预设规则时才会终止循环。 - 利用了 `fmt.Scanln` 的特点——不仅能够读取指定数量的参数还负责确认之后没有多余的未消费字符存在[^4]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值