Go语言中如何避免Scan读取用户输入的所有字符?
解决随机团队生成器输入验证重复报错问题
原代码里,当用户输入非数字内容时会重复输出错误提示,核心原因是无效输入会留在标准输入缓冲区中,fmt.Scan每次循环都会读取到这些无效内容,导致多次触发错误。
要解决这个问题,只需在检测到输入错误时清空缓冲区里的无效内容,确保下一次循环能等待新输入,且仅输出一次错误提示。
修改后的完整代码如下:
// Dan Bell // 随机团队生成器 package main import ( "bufio" "fmt" "log" "math/rand" "os" "strings" "time" ) func main() { var mySlice []string // 打开同目录下的names.txt文件 f, err := os.Open("names.txt") if err != nil { log.Fatal(err) } defer f.Close() // 将文件内容扫描到切片中 scanner := bufio.NewScanner(f) for scanner.Scan() { mySlice = append(mySlice, scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } // 打乱切片顺序,保证每次分组随机 rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(mySlice), func(i, j int) { mySlice[i], mySlice[j] = mySlice[j], mySlice[i] }) fmt.Println("\n欢迎使用团队生成器\n\n\n请输入每组团队的人数:") var teamSize int inputScanner := bufio.NewScanner(os.Stdin) // 输入验证循环 for { // 读取整行输入 if !inputScanner.Scan() { log.Fatal(inputScanner.Err()) } input := inputScanner.Text() // 尝试将输入转换为整数 _, err := fmt.Sscanf(input, "%d", &teamSize) if err != nil { fmt.Println("\n请输入有效的数字!") } else { break } } var divided [][]string // 将切片按指定人数分组 for i := 0; i < len(mySlice); i += teamSize { end := i + teamSize if end > len(mySlice) { end = len(mySlice) } divided = append(divided, mySlice[i:end]) } // 打印各组名单 for i := 0; i < len(divided); i++ { fmt.Printf("\n第%d组\n%s\n", i+1, strings.Join(divided[i], ", ")) } }
修改说明
- 改用
bufio.Scanner读取整行输入,避免fmt.Scan只读取部分内容导致缓冲区残留的问题; - 用
fmt.Sscanf解析整行输入,无论输入多长的非数字字符串,只会触发一次错误提示; - 变量名调整为符合Go语言规范的
mySlice,提升代码可读性; - 输出文本替换为中文,适配中文使用场景。
内容的提问来源于stack exchange,提问作者dannybellboy
相关产品推荐
相关产品推荐

