我有简单的程序可以将里程转换为公里数:
const kmInMile = 1.609344
func main() {
var miles float64
fmt.Print("Enter miles: ")
fmt.Scanf("%f", &miles)
fmt.Println(miles)
km := kmInMile * miles
fmt.Println(miles, "miles =", km, "km")
}
如果我将“lls”作为scanf的输入传递:
Enter miles: lls
输出是:
0
0 miles = 0 km
alexandrkrivosheev$ ls
hello main.go
所以输入了第一个字符,其他所有字符都是作为命令执行。 为什么会发生这种情况?如何防止这种情况发生?
完整终端会议:
alexandrkrivosheev$ ./hello
Enter miles: lls
0
0 miles = 0 km
alexandrkrivosheev$ ls
hello main.go
alexandrkrivosheev$
答案 0 :(得分:4)
使用“plain fmt.Scanf”时,输入必须与预期的格式匹配,即在您的情况下,它必须是有效的float。如果不是则则中止扫描并且输入的其余部分保留在控制台的输入缓冲区中,在程序退出后将其作为下一个命令执行。
要解决此问题,请将标准输入包装成bufio.Reader
或bufio.Scanner
:
func main() {
var miles float64
fmt.Print("Enter miles: ")
//
reader := bufio.NewReader(os.Stdin)
val, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
if _, err = fmt.Sscanf(val, "%f", &miles); err != nil {
fmt.Println(val, err)
return
}
fmt.Println(miles)
km := kmInMile * miles
fmt.Println(miles, "miles =", km, "km")
}
这样您就可以从输入中消耗整行并单独处理它。