我正在寻找与scanf()等效的Go.我尝试使用以下代码:
1 package main
2
3 import (
4 "scanner"
5 "os"
6 "fmt"
7 )
8
9 func main() {
10 var s scanner.Scanner
11 s.Init(os.Stdin)
12 s.Mode = scanner.ScanInts
13 tok := s.Scan()
14 for tok != scanner.EOF {
15 fmt.Printf("%d ", tok)
16 tok = s.Scan()
17 }
18 fmt.Println()
19 }
Run Code Online (Sandbox Code Playgroud)
我使用带有一行整数的文本输入来运行它.但它总是输出-3 -3 ......
以及如何扫描由字符串和一些整数组成的行?遇到新数据类型时更改模式?
包文档:
包扫描仪
用于UTF-8编码文本的通用扫描仪.
但似乎扫描仪不适用于一般用途.
更新的代码:
func main() {
n := scanf()
fmt.Println(n)
fmt.Println(len(n))
}
func scanf() []int {
nums := new(vector.IntVector)
reader := bufio.NewReader(os.Stdin)
str, err := reader.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
i, _ := strconv.Atoi(f)
nums.Push(i)
}
str, err = reader.ReadString('\n')
}
r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
r[i] = nums.At(i)
}
return r
}
Run Code Online (Sandbox Code Playgroud)
改良版:
package main
import (
"bufio"
"os"
"io"
"fmt"
"strings"
"strconv"
"container/vector"
)
func main() {
n := fscanf(os.Stdin)
fmt.Println(len(n), n)
}
func fscanf(in io.Reader) []int {
var nums vector.IntVector
reader := bufio.NewReader(in)
str, err := reader.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
if i, err := strconv.Atoi(f); err == nil {
nums.Push(i)
}
}
str, err = reader.ReadString('\n')
}
return nums
}
Run Code Online (Sandbox Code Playgroud)
更新后的代码在没有行号的情况下更容易编译,但缺少包和导入语句。
看着你的代码,我注意到了一些事情。这是我对您的代码的修改版本。
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
"container/vector"
)
func main() {
n := scanf(os.Stdin)
fmt.Println()
fmt.Println(len(n), n)
}
func scanf(in io.Reader) []int {
var nums vector.IntVector
rd := bufio.NewReader(os.Stdin)
str, err := rd.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
if i, err := strconv.Atoi(f); err == nil {
nums.Push(i)
}
}
str, err = rd.ReadString('\n')
}
return nums
}
Run Code Online (Sandbox Code Playgroud)
我可能想使用任何输入文件scanf()
,而不仅仅是Stdin
; scanf()
以 anio.Reader
作为参数。
您写道:nums := new(vector.IntVector)
,哪里type IntVector []int
。这将分配一个名为 的整数切片引用nums
并将其初始化为零,然后该new()
函数分配一个整数切片引用并将其初始化为零,然后将其分配给nums
。我写了: ,它通过简单地分配一个名为 name 的整数切片引用并将其初始化为零var nums vector.IntVector
来避免冗余。nums
您没有检查err
的值strconv.Atoi()
,这意味着无效输入被转换为零值;我跳过它。
要将向量复制到新切片并返回切片,您可以编写:
r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
r[i] = nums.At(i)
}
return r
Run Code Online (Sandbox Code Playgroud)
首先,我简单地将其替换为等效方法IntVector.Data()
:return nums.Data()
。然后,我利用这一事实type IntVector []int
,通过将其替换为: 来避免分配和复制return nums
。