
在使用 fmt.Scanf() 从标准输入读取数据时,如果用户输入了无效的数据,例如期望输入整数却输入了字符串,fmt.Scanf() 会返回一个错误,并且无效的输入会残留在标准输入缓冲区中。在循环中重复调用 fmt.Scanf() 时,由于缓冲区中仍然存在无效数据,程序会不断地读取到这些数据,导致无限循环。
解决这个问题的一种有效方法是使用 bufio 包来创建一个带缓冲的读取器,并在每次读取失败后清除缓冲区。bufio.NewReader 函数可以创建一个新的带缓冲的读取器,它从指定的 io.Reader 读取数据,这里我们可以使用 os.Stdin 作为输入源。bufio.Reader 提供了 ReadString(‘n’) 方法,可以读取直到遇到换行符为止的所有数据,并将这些数据从缓冲区中清除。
以下是一个示例代码,演示了如何使用 bufio 包来清除 fmt.Scanf() 后的标准输入缓冲区:
package mainimport ( "bufio" "fmt" "os")func main() { stdin := bufio.NewReader(os.Stdin) fmt.Println("Please enter an integer: ") var userI int for { _, err := fmt.Fscan(stdin, &userI) if err == nil { break } stdin.ReadString('n') // 清除缓冲区 fmt.Println("Sorry, invalid input. Please enter an integer: ") } fmt.Println(userI)}
代码解释:
立即学习“go语言免费学习笔记(深入)”;
stdin := bufio.NewReader(os.Stdin): 创建一个新的带缓冲的读取器,它从标准输入 os.Stdin 读取数据。_, err := fmt.Fscan(stdin, &userI): 使用 fmt.Fscan 从带缓冲的读取器 stdin 读取一个整数,并将其存储到变量 userI 中。 fmt.Fscan 类似于 fmt.Scanf,但它从 io.Reader 读取数据,而不是直接从标准输入读取。stdin.ReadString(‘n’): 如果读取失败(err != nil),则调用 stdin.ReadString(‘n’) 来读取并丢弃缓冲区中剩余的数据,直到遇到换行符为止。 这有效地清除了缓冲区中的无效输入。
运行示例:
如果用户输入有效的整数,程序会正常读取并输出:
Please enter an integer:33
如果用户输入无效的字符串,程序会提示用户重新输入,并清除缓冲区,避免无限循环:
Please enter an integer:what?Sorry, invalid input. Please enter an integer:55
注意事项:
使用 bufio 包可以有效地处理标准输入缓冲区中的残留数据,避免无限循环。ReadString(‘n’) 方法会一直读取直到遇到换行符,如果用户输入的数据中没有换行符,程序可能会一直阻塞。 在实际应用中,可以设置读取超时来避免这种情况。除了 ReadString(‘n’) 方法,bufio.Reader 还提供了其他方法来读取数据,例如 ReadBytes 和 ReadLine,可以根据实际需求选择合适的方法。
总结:
本文介绍了如何使用 bufio 包来清除 fmt.Scanf() 后的标准输入缓冲区,避免由于无效输入导致的无限循环。通过使用 bufio.NewReader 和 ReadString(‘n’) 方法,我们可以有效地处理标准输入,并提供更友好的用户体验。 掌握这种技巧对于编写交互式命令行程序至关重要。
以上就是如何在Go语言中使用bufio清除fmt.Scanf()后的Stdin缓冲区的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1409051.html
微信扫一扫
支付宝扫一扫