Golang中STD I/O函数的一个小但烦人的问题
Golang中STD I/O函数的一个小但烦人的问题 你好,我是Go语言的新手,但之前一直在用C++编程。我决定学习Go,对我来说,最好的方法就是看一些结构化的视频教程,然后去解决SPOJ、Codeforces等平台上的编程问题。
我现在正在尝试解决一个几乎微不足道的问题,因为它的逻辑并不复杂,但我觉得我在标准输入部分遇到了问题,想看看这里是否有人能帮我。我一直在试图弄清楚为什么会发生这种情况,但还没有找到确切的答案。
以下是输入示例、我得到的输出,以及问题的链接(如果你想知道的话): (输入示例) 2 2 1 2 3 4 3 1 2 3 4 5 6
(输出示例) [1 1] [3 3] [1 3 4] [6 6 6]
(问题链接)
SPOJ.com - Problem FASHION
我目前的怀疑是问题出在fmt.Scanf上,好像它没有在控制台行中逐个元素地前进,而总是读取同一个第一个元素(这听起来很荒谬),但我还没有找到任何解释其原因的资料,甚至连函数描述里也没有。
非常感谢。
package main
import (
"fmt"
)
func main() {
var (
cases, couples int
array []int
array2 []int
x int
// suma int = 0
)
fmt.Scanln(&cases)
for i := 0; i < cases; i++ {
fmt.Scanln(&couples)
array = nil
for j := 0; j < couples; j++ {
fmt.Scanf("%d ", &x)
array = append(array, x)
}
fmt.Println(array)
array2 = nil
for j := 0; j < couples; j++ {
//fmt.Println("flag")
fmt.Scanf("%d ", &x)
array2 = append(array2, x)
//suma += 0
}
fmt.Println(array2)
}
}
更多关于Golang中STD I/O函数的一个小但烦人的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
不要忽略从 Scan 返回的错误。它可能提供线索。
更多关于Golang中STD I/O函数的一个小但烦人的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
嘿,谢谢你的回复。我已经解决了这个问题,不得不使用 bufio.Scanner、strings.Split 和 strconv.Atoi。虽然问题解决了,但我仍然想知道为什么会发生这个错误,我打算继续研究一下。
我会使用 strings 包 - strings - pkg.go.dev 和 strconv 包 - strconv - pkg.go.dev。这里展示了如何逐行读取文件 逐行读取文件(标准输入) · YourBasic Go。
问题出在fmt.Scanf("%d ", &x)中的空格格式符。在Go的fmt.Scanf中,尾随空格会导致函数持续读取输入直到遇到非空白字符,这会造成读取行为异常。
以下是修正后的代码:
package main
import (
"fmt"
)
func main() {
var cases, couples int
fmt.Scanln(&cases)
for i := 0; i < cases; i++ {
fmt.Scanln(&couples)
array := make([]int, couples)
for j := 0; j < couples; j++ {
fmt.Scanf("%d", &array[j])
}
fmt.Println(array)
array2 := make([]int, couples)
for j := 0; j < couples; j++ {
fmt.Scanf("%d", &array2[j])
}
fmt.Println(array2)
}
}
更简洁的替代方案是使用fmt.Scan:
package main
import (
"fmt"
)
func main() {
var cases, couples int
fmt.Scan(&cases)
for i := 0; i < cases; i++ {
fmt.Scan(&couples)
array := make([]int, couples)
for j := 0; j < couples; j++ {
fmt.Scan(&array[j])
}
fmt.Println(array)
array2 := make([]int, couples)
for j := 0; j < couples; j++ {
fmt.Scan(&array2[j])
}
fmt.Println(array2)
}
}
对于竞赛编程,推荐使用bufio.Scanner以获得更好的性能:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
cases, _ := strconv.Atoi(scanner.Text())
for i := 0; i < cases; i++ {
scanner.Scan()
couples, _ := strconv.Atoi(scanner.Text())
scanner.Scan()
nums1 := strings.Fields(scanner.Text())
array := make([]int, couples)
for j := 0; j < couples; j++ {
array[j], _ = strconv.Atoi(nums1[j])
}
fmt.Println(array)
scanner.Scan()
nums2 := strings.Fields(scanner.Text())
array2 := make([]int, couples)
for j := 0; j < couples; j++ {
array2[j], _ = strconv.Atoi(nums2[j])
}
fmt.Println(array2)
}
}
关键点:在Go的fmt.Scanf中避免使用尾随空格格式符,它们会导致意外的读取行为。

