华为笔试时发现golang ACM模式输入的一个坑
golang ACM模式常用输入方法(scan,bufio):https://zhuanlan.zhihu.com/p/551393704
问题
第二行输入完n3后,行末尾存在空格+回车,n4不会被读入数据。
func main() {
var n1,n2,n3,n4 int
fmt.Scanln(&n1)
// 如果在输入完n3后,输入空格+回车 会报错
fmt.Scan(&n2,&n3)
fmt.Scanln(&n4)
fmt.Println(n1,n2,n3,n4)
}
程序的运行结果如下:
测试过程
为了分析问题,我们可以分别输出这三个输入函数的err和int返回值大小
func main() {
var n1,n2,n3,n4 int
len1,err1 := fmt.Scanln(&n1)
len2,err2 := fmt.Scan(&n2,&n3)
len3,err3 := fmt.Scanln(&n4)
fmt.Println(n1,n2,n3,n4)
fmt.Println(len1,err1)
fmt.Println(len2,err2)
fmt.Println(len3,err3)
}
此次程序运行结果:
可以看到,是因为换行符导致err3的出现。但令我不解的是,如果将第三行的Scanln换成Scan,或者第二行的Scan换成Scanln均能顺利输入
func main() {
var n1,n2,n3,n4 int
// 将第二行的Scan换成Scanln
len1,err1 := fmt.Scanln(&n1)
len2,err2 := fmt.Scanln(&n2,&n3)
len3,err3 := fmt.Scanln(&n4)
// 将第三行的Scanln换成Scan
len1,err1 := fmt.Scanln(&n1)
len2,err2 := fmt.Scan(&n2,&n3)
len3,err3 := fmt.Scan(&n4)
fmt.Println(n1,n2,n3,n4)
fmt.Println(len1,err1)
fmt.Println(len2,err2)
fmt.Println(len3,err3)
}
两端程序的输出结果相同,输出结果如下:
结论
根据测试得出结论,如果输入数据的行结尾存在 “空格 + 换行符” 如果这一行是用Scan读取输入的话,下一行不能用Scanln读取输入,否则会出现unexpected newline
的error。其它情况(Scan+Scan,Scanln+Scan,Scanln+Scanln)均可正常读入数据,为了规范还是建议Scan和Scanln不要混用,很容易出现问题。
通过查看源码也没有找到为什么输入数据的行结尾存在 "空格 + 换行符"的情况下在先用Scan再用Scanln会出现问题,希望能得到大佬的指教!!!